プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

C# dataGridViewとキャストと型変換のあれこれ

いろいろはまった

C#においてExcellのように扱えるオブジェクトdataGridViewですが、扱いにはクセがあります(仕様であり個人の感想でしかなく、仕様嫁)。
f:id:s51517765:20210905152308p:plain

セルの値を数値解釈(変換)できるかどうか

セルに値を入力したときは基本的に文字列として受け取ります。
これをのちのち数値変換するので数値解釈(変換)できないときはその入力をキャンセルしたい、ということを考えました。

入力があったとき発動するアクションを設定したいので、似たような下記3つのアクションのうちここでは3番になります。
1番は入力前、セル選択時に発動するので該当セルが空白の状態で動作します。
2番は単独ではこれでも動きますが、他の関数からセルに入力されたりしたときにも動きます。
3番が手動入力のみに発動します。

//1
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
    //セルを選択したときに動く
}

//2
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    //他の関数から書き込みしたときも動く
}

//3
private void dataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e)
{
    //セルの入力が完了したときに動く
}

セルの入力を空白(削除)にする。

""にしたくなりますが、これは何も起きません。nullを与えます。

//×
dataGridView1[e.ColumnIndex, e.RowIndex].Value = "";

//〇
dataGridView1[e.ColumnIndex, e.RowIndex].Value = null;

セルの値を数値変換する

先に述べたとおりdataGridViewに持たせられる「数値」は文字列になります。
何かしらの計算を行うには数値に変換する必要があります。
ここにたとえば文字列"1"を与えたとすると、

//1 × 構文エラー、dataGridView1[1, 1].Valueはオブジェクトのため
double L1 = double.Parse(dataGridView1[1, 1].Value);

//2 構文的には〇、 double.Parseが受け取るのはString
double L1 = double.Parse(dataGridView1[0, i].Value.ToString());

//3 構文的には〇、 double.Parseが受け取るのはString
double L1 = double.Parse((String)dataGridView1[0, i].Value);

//4 構文的には〇、(double)が受け取る型は何でもいい?
L1 = (double)dataGridView1[0, i].Value;

(double)(String)はキャストといわれる型変換で、ToString()は文字列表現を得るものです。
いずれも数値変換不可能な文字列が与えられたときは例外が発生します。
数値変換可能なことが保証されていれば4でよい気がします。

数値変換可能かどうか

変換可能かどうかわからないときはdouble.TryParseで変換可能か否かを取得します。
以下ではtrueのときその数値を取得し、falseのときnullにします。

if (double.TryParse(dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString(), out m) == true)
//if (double.TryParse((String)dataGridView1[e.ColumnIndex, e.RowIndex].Value, out m) == true)
{
    dataGridView1[e.ColumnIndex, e.RowIndex].Value = m; //列,行
}
else
{
    dataGridView1[e.ColumnIndex, e.RowIndex].Value = null;
}

まとめ

C#で文字列その他の数値変換を扱う方法について調べたら結構複雑でした、という話でした。