DOBON.NET DOBON.NETプログラミング掲示板過去ログ

DataGridView上のMaskedTextBoxの日付フォーマットについて

環境/言語:[環境(XP),使用言語(VB2005+SQLServer2005)]
分類:[.NET]

お世話になっております。

DetaGridView上でMaskedTextBoxを使用する為に
こちらのサイトのサンプルをお借りして一先ずテスト用のフォームに表示させてみました。
『DataGridViewにMaskedTextBoxを表示する』

デザイナで作成したデータセットをデータソースウィンドから
フォームにドラッグしてグリッドを作成、
グリッドプロパティの列の編集から日付型のフィールドを
DataGridViewMaskedTextBoxColumnに変更して実行してみました。

日付入力の設定はyy/MM/ddとしたかった為Maskプロパティには00/00/00
DataGridViewCellStyleのFormatはyy/MM/ddとしてあります。

問題点としてはまずセルをクリックして編集モードの入るとなぜか一番最初は空白で表示されます。
次に別の列のセルをクリックするとデータは表示されますが
20/10/06と8桁の日付の先頭を持ってきてしまいます。

ちなみに表示のみの場合は正常です。
10/06/28を編集しようとクリックしてEditModeに入ると20/10/06に変わるといった感じです。
通常のフォームに張り付けたMaskedTextBoxでは問題なく動いている設定と
同じ事をしてるはずのなのですがうまく動いてくれません。


ここを見直せ、この辺りを調べろ等お気づきの点がございましたらアドバイスお願いします。
http://dobon.net/vb/dotnet/datagridview/maskedtextboxcolumn.html
これですね。

二つ原因があります。いずれも DataGridViewMaskedTextBoxCell.InitializeEditingControl メソッド内のことです。

まず、MaskedTextBox.Text に this.Value.ToString() を使ってる点。
DateTime にバインディングしているので this.Value は DateTime 型になり、そのまま ToString() した場合日本語環境だと yyyy/MM/dd H:mm:ss って感じに書式化されるため、頭から順に数字六桁、つまり年四桁月二桁が 00/00/00 という Mask によって割り当てられることになります。
これが
> 別の列のセルをクリックするとデータは表示されますが20/10/06と8桁の日付の先頭を持ってきてしまいます。
の原因です。

次に、MaskedTextBox.Mask プロパティを一連の処理の最後に設定している点。
一番初めにその行の DataGridViewMaskedTextBoxColumn 列のエディットモードに入った時点では、まだ MaskedTextBox.Mask は空です。このとき、上述の通りの処理によって MaskedTextBox.Text には yyyy/MM/dd H:mm:ss か何かに書式化された日時文字列が、(Mask が空なので)そのまま格納されます。
で、その後 MaskedTextBox.Mask が設定されますが、ここで MaskedTextBox.Mask の解説にある動作が問題を引き起こします。
> MaskedTextBox が、前のマスクでフィルタ処理されたユーザー入力を既に含んでいる場合にマスクを変更すると、
> MaskedTextBox はその入力を新しいマスク定義に移行しようとします。
> 移行に失敗すると、既存の入力が消去されます。
つまり、既に設定されている yyyy/MM/dd H:mm:ss は新たに設定したマスク 00/00/00 に一致しないので Text が空に設定されてしまうわけです。
これが
> セルをクリックして編集モードの入るとなぜか一番最初は空白で表示されます。
の原因になります。


取り敢えずの解決策としては、MaskedTextBox.Text を設定する際に this.Value を使う代わりに this.FormattedValue を使うことでしょうか。DateTime オブジェクトではなく、DataGridViewCellStyle.Format が適用済みの文字列、つまり yy/MM/dd で書式化された文字列を取得することができます。
それから一応念のため MaskedTextBox.Mask の設定は MaskedTextBox.Text よりも前に持ってくるのもやっておいた方が良いでしょう(実際には FormattedValue だけで問題はないんですが。Text を yy/MM/dd に設定した後で Mask に 00/00/00 を設定してもちゃんとマスクできますから)。
// ただ、これらが DataGridViewMaskedTextBoxCell に対する普遍的な解決策かどうかは保証できません。

MonthCalendar や DateTimePicker をホストする DataGridViewColumn を作るというのも一案かもしれません。
>>Hongliang様
詳しく解り易いご回答ありがとうございます!

ブレイクポイントを置いて見ていた所maskedBox.Textの時点で'20/10/06'になっておりましたので
DataGridViewMaskedTextBoxEditingControlで何かが起こっていると思って調べてはいたのですが;
this.Value、this.FormattedValueこの2つのキーワードを調べた上でやり直してみたいと思います。

結果はまた後ほどご報告させて下さい。

DOBON.NET | プログラミング道 | プログラミング掲示板