プログラミングと日々思ったことなど

ブログ名通りです。仕事でプログラミングをはじめました。

DataGridの必須入力チェック【WPF】

今週も頑張りました。
オブジェクト指向の前に、昨日の復習を記事にします(難しかった・・・)

昨日会社で教えてもらったのは、DataGridの必須入力チェックです。
DataGridに表示されているデータを編集したとき、必須項目が未入力だった際にその項目の枠が赤くなり、かつ、「必須エラーです」とメッセージが表示される処理です。

この必須入力チェックは、登録ボタン(コマンド)を押すと処理されます。
まずコマンド内でどの項目がエラーなのか判別処理・表示文章設定します。
その後ViewのTargetUpdated内で、実際にエラーメッセージが表示されるように処理していきました。


DataGridViewModel.cs
//このbtnRegist_Clickは、登録ボタンのコマンドに仕込んであるもの。
public void btnRegist_Click()
{
	bool isError = this.DtoCheck();

	//チェック処理
	if(isError)
	{
		this.RaisePropertyChanged("Views");
		return;
	}

	if(MessageBoxResult.Yes == System.Windows.MessageBox.Show("変更項目を登録しますか?","登録変更確認",MessageBoxButton.YesNo))
	{
		testDataGridModel model =
			new testDataGridModel(this.Dto);
		model.InsertData(updateflag);

		//登録変更が成功したか

		isSuccess = model.IsSuccess;
		if(isSuccess)
		{
			//略...登録更新の成功・失敗メッセージ処理...
		}
	}
}

private bool DtoCheck()
{
	bool isError = false;
	//エラーフィールドのクリア
	//ここで中身をクリアにしておかないと、連続処理したときに前の処理が残ってしまう。
	foreach(DataRow dr in this.Dto.testData.Rows)
	{
		dr["ERROR_FIELD"] = string.Empty;
		dr["ERROR_MSG"] = string.Empty;
		dr.ClearErrors();
	}

        //foreachの中にforeachでRowとColumnを1つずつ取り出している(結果1つのCellずつ処理ができる)
	foreach(DataRow dr in this.dto.testData.Rows)
	{
		//testDataの列を一列ずつ読み込む
		foreach(DtaColumn dc in this.dto.testData.Columns)
		{
			//必須か選択項目か確認 
			if(sentakuFields(dc.ColumnName))
			{
				continue;
			}

			if((dr[dc.ColumnName] == null) || (dr[dc.ColumnName].Tostring() == string.Empty))
			{
				//ここで空のERROR_FIELD行の中身を作っている
				if(dr["ERROR_FIELD"].Tostring() == string.Empty)
				{
					dr["ERROR_FIELD"] = dc.ColumnName;
				}
				else
				{
					dr["ERROR_FIELD"] += " " + dc.ColumnName; //区切り指定
				}

				dr["ERROR_MSG"] = dc.ColumnName + "で必須エラーです。¥r¥n";
				dr.RowError = dc.ColumnName + "で必須エラーです。¥r¥n";
				dr.SetColumnError(dc,dr["ERROR_MSG"].Tostring());

				isError = true;
			}
		}
	}
	return isError;

}

//選択項目を、ここで抜き出し
private bool sentakuFields(string strFieldName)
{
	bool isSentaku = false;

	switch(strFieldName)
	{
		case "aa":
		case "bb":

		isSentaku = true;
		break;
	}

	return isSentaku;
}
	
DataGrid.cs(View)
public test()

{
	InitializeComponent();

	//画面が表示されたときに、色々なデータを取得する処理
	ThisForm = ExPageParamsUtil.GetPageParams("TForms") as ExMenuWindow;
	//...略

	this.DataContext =
		new testViewModel(CommonTbls,exWin,cmbAuth);
	this.testDataGrid.TargetUpdated += 
	new EventHandler<DataTransferEventArgs>(testDataGrid_TargetUpdated);

}

private void testDataGrid_TargetUpdated(object sender,DataTransferEventArgs e)
{
	//エラー内容のクリア
	for(int idx = 0;idx < this.testDataGrid.Rows.Count;idx++)
	{
		this.testDataGrid.Rows[idx].Errors.Clear();
	}

	BindingListCollectionView chkView =
		this.testDataGrid.ItemSorce as BindingListCollectionView;

	//フィルタかける前のすべてのデータを取得する。
	DataTable dt = ((DataView)chkView.SorceCollection).ToTable().Copy();

	//フィルタ圧縮かける <>''←これは値が入っているかどうかを判断することができる。
        //RowFiletrで圧縮をかけると、番号がおかしくなるので注意。
	DataRow[] drs = dt.Select("ERROR_FIELD<>''");

	foreach(DataRow dr in drs)
	{
		//エラー項目及びエラー内容の取得
		DataGridRowError dgErr = new DataGridRowError();
		string[] errField = dr["ERROR_FIELD"].Tostring().Split('');

		foreach(string fld in errField)
		{
			dgErr.ColumnsNames.Add(fld);
			dgErr.Message = dr.GetColumnError(fld);

			//エラーオブジェクトを対象データグリッド行にセットする

			//エラー行番号の取得
			int intRowIdx = dt.Rows.IndexOf(dr);
			//データグリッドエラー対象行にエラーセット
			this.testDataGrid.Rows[intRowIdx].Errors.Add(dgErr);
		}
	}
}

以上なのですが、このコードだとセレクターにメッセージが表示されません。
どうすれば良いのか、調べてみようと思います。


-----ここから雑記

教えてもらっていたのに、復習してみるとわかっていないところが出てきました。
書いてみるとわかっていないところがわかるので、これからもコードを書いていこうと思います。

あと、色々コードを教えてもらっていて思っていたことを、昨日やっと聞くことができました。
foreachの中に、foreachやifが入っているのが変な感じがしていたのですが、それは処理が多くなりそうであれば、別のメソッドへ飛ばしても良いそうです。

些細なことも答えてくれる先輩方が、会社にたくさんいるのがとてもありがたいです。

そういやボーナスは出るのかなー。
出たらマイコンキットか、Windowsを購入したいのです・・・うーん難しいかな・・・。