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を購入したいのです・・・うーん難しいかな・・・。