下記参考(1) に従って検証を見直しています。
参考(1) は検証対象の Column/Cell を指定していますが、DataGridView の数
が少ない時はいいのですが、増えてくると指定が面倒だろうな、と予想してい
ます。
そこで、DataGridView に BindingSource を設定したら、NotNull の検証が必
要な Column/Cell を直接指定せずに、プログラムで CellValidating 時に
NotNull を自動検証してくれるようにしたい、と考えています。
で、NotNull か否かは DataColumn.AllowDBNull で分かりますから、
それをあらかじめ調べておけばいいんじゃないか?と思っているのですが、
何かもっと楽な方法はあるのでしょうか? 皆さん、どういう風にされてますか?
DataError を拾うって方法だと、e.Exception.Message で内容は分かりますが、
プログラム寄りのメッセージのため、ユーザーに見せたくはありません。
参考
(1) チュートリアル : Windows フォーム DataGridView コントロールのデータの妥当性検査
(2) チュートリアル : Windows フォーム DataGridView コントロールでのデータ入力中に発生したエラーの処理
私は以下のように、DataGridView の BindingSource からたどって DataTable
を取得して、それから DataColumn を扱おうとしました。
Code Snippet
public partial class DataGridViewEx : DataGridView
{
List<string> notNulls = new List<string>();
public void checkDBNull() .................................................... (1)
{
if (this.DataSource != null)
{
BindingSource bindingSource = (BindingSource)this.DataSource;
string tableName = this._getTableName(bindingSource.DataMember);
syllabaryDataSet dataSet = (syllabaryDataSet)this._getDataSet(this.DataSource);
if (dataSet != null)
{
DataTable dataTable = dataSet.Tables[tableName];
foreach (DataColumn dcol in dataTable.Columns)
{
if (!dcol.AllowDBNull)
{
notNulls.Add(dcol.ColumnName);
}
}
}
}
}
private object _getDataSet(object dataSource) ................................ (2)
{
if (dataSource is DataSet)
{
return dataSource;
}
else if (dataSource is BindingSource)
{
return this._getDataSet(((BindingSource)dataSource).DataSource);
}
return null;
}
private string _getTableName(string dataMember) .............................. (3)
{
List<string> tokens = new List<string>(dataMember.Split(new char[] {'_'}));
return (tokens.Contains("FK")) ? tokens[1] : tokens[0];
}
- (1)
- これを呼び出して、NotNull なフィールド名を抽出。
- (2)
- DataGridView.DataSource から再帰的に DataSet を探し出す。
- (3)
- テーブル名や連結の文字列はある命名規則を設けているので、それに従って、
必要なテーブル名を抽出。例えば、以下のような親子関係の BindingSource の
連結に備えて。
Code Snippet
this.columnsBindingSource.DataMember = "columns";
this.columnsBindingSource.DataSource = this.syllabaryDataSet;
|
+-------------------------------+
V
this.charsBindingSource.DataSource = this.columnsBindingSource;
this.charsBindingSource.DataMember = "FK_chars_columns";
以上で、NotNull な Column を抽出しておいて、検証時に使おうかと考えました。
今の私の知識だけだと、こんな感じにしかなりません。
もっと楽な方法がありましたら、アドバイスを宜しくお願いします。
+ 追記 (2008-03-28)
特に重要ではなくなったので「質問」から「コメント」に変更。