【C#】【Form】DataGridView ~イベント編 ~

■ DataGridViewのイベント

CellDoubleClick

 * セルのダブルクリックイベント
使用上の注意
 * ヘッダーをダブルクリックした時も呼ばれる
【対応方法】
 * 「e.RowIndex < 0」で判断する
【対応例】
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
  if (e.RowIndex < 0)
  {
    // ヘッダーをダブルクリックしたら特に何もしない
    return;
  }

  // ここから実装する

  var dataGridView = sender as DataGridView;
  MessageBox.Show(dataGridView[e.ColumnIndex, e.RowIndex].Value.ToString());
}
参考文献
http://heppoen.seesaa.net/article/435645261.html

CellContextMenuStripNeeded

 * セルの右クリック押下時に発生

 * サンプルは、以下の記事「DataGridView に右クリックを適用する」を参照のこと
http://blogs.yahoo.co.jp/dk521123/30488275.html

CellParsing / CellFormatting

 * 入力された値を変換する / 表示時に値を変換する

■ サンプル

例1:CellFormattingイベントで値によって表示を変える

 * CellFormattingイベントで値によって表示を変える
  => これを使えば、列挙型の値も表示で変更できる
 * 以下のサイトを参考。
https://dobon.net/vb/dotnet/datagridview/cellformattingvalue.html
 * 事前に DataGridView に 項目として Id/PersonName/Ageを追加しておく
Form1.cs
using System;
using System.Windows.Forms;

namespace SampleForm
{
  public partial class Form2 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      this.dataGridView1.Rows.Add(1L, "Mike", 26);
      this.dataGridView1.Rows.Add(2L, "Tom", 41);
      this.dataGridView1.Rows.Add(3L, "Smith", 29);
      this.dataGridView1.Rows.Add(4L, "Naomi", 38);
      this.dataGridView1.Rows.Add(5L, "Kevin", 24);
    }

    private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
      DataGridView dataGridView = (DataGridView)sender;

      // セルの列を確認
      if (dataGridView.Columns[e.ColumnIndex].Name == "Age" && e.Value is int)
      {
        var value = Convert.ToInt32(e.Value);
        if (value <= 27)
        {
          e.Value = "若手";
        }
        else if (value >= 28 && value <= 39)
        {
          e.Value = "中堅";
        }
        else
        {
          e.Value = "シニア";
        }

        // フォーマットの必要がないことを知らせる
        e.FormattingApplied = true;
      }
    }
  }
}

例2

 * 入力した値がDataTime型なら、CellParsingイベントにより、「yyyy/MM/dd」に変換する
 * 表示時に、値がDataTime型なら、CellFormattingイベントで、年齢に変換する

って、ゆークラス・ExtendDataGridViewを作成
ExtendDataGridView.cs
public class ExtendDataGridView
{
    private readonly string columnName;

    private ExtendDataGridView(DataGridView dataGridView, string columnName)
    {
        this.columnName = columnName;

        dataGridView.CellParsing += CellParsing;
        dataGridView.CellFormatting += CellFormatting;
    }

    public static void Attach(DataGridView dataGridView, string columnName)
    {
        new ExtendDataGridView(dataGridView, columnName);
    }

    private void CellParsing(object sender, DataGridViewCellParsingEventArgs e)
    {
        DataGridView dataGridView = sender as DataGridView;

        if (dataGridView == null)
        {
            return;
        }

        int columnIndex = e.ColumnIndex;

        if (dataGridView.Columns[columnIndex].Name == this.columnName &&
            e.Value != null &&
            e.DesiredType == typeof(string))
        {
            var birthDay = e.Value.ToString();

            DateTime birthDate;
            if (!DateTime.TryParse(birthDay, out birthDate))
            {
                return;
            }

            e.Value = birthDate.ToString("yyyy/MM/dd");
            e.ParsingApplied = true; // 解析が不要であることを通知
        }
    }

    private void CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        DataGridView dataGridView = sender as DataGridView;

        if (dataGridView == null)
        {
            return;
        }

        if (dataGridView.Columns[e.ColumnIndex].Name == this.columnName &&
            e.Value != null &&
            e.DesiredType == typeof(string))
        {
            var birthDay = e.Value.ToString();

            DateTime birthDate;
            if (!DateTime.TryParse(birthDay, out birthDate))
            {
                return;
            }
            double totalDays = DateTime.Now.Subtract(birthDate).TotalDays;
            int age = (int)(totalDays / 365);

            e.Value = age.ToString();
            e.FormattingApplied = true; //フォーマットの必要がないことを知らせる
        }
    }
}
Form1.cs
public partial class Form1 : Form
{
    public NUnitSampleForm()
    {
        InitializeComponent();

        ExtendDataGridView.Attach(this.dataGridView1, "Column2");
    }
}


関連記事

Windows Form ~ 目次 ~

https://blogs.yahoo.co.jp/dk521123/8054245.html

DataGridView

DataGridView ~ プロパティ編 ~
https://blogs.yahoo.co.jp/dk521123/14718079.html
DataGridView ~イベント編 ~
https://blogs.yahoo.co.jp/dk521123/23687833.html
DataGridView ~ ソート編 ~
https://blogs.yahoo.co.jp/dk521123/37914797.html
DataGridView を Label のように扱う
https://blogs.yahoo.co.jp/dk521123/29362064.html
DataGridView に ACCESS のデータを表示させる
https://blogs.yahoo.co.jp/dk521123/32859068.html
DataGridView に右クリックを適用する
https://blogs.yahoo.co.jp/dk521123/30488275.html