2006年09月21日

DataGridViewの列毎に数字のみ入力許可を与える方法

前回、列毎にIMEを制御する方法を紹介したので、今度はIMEをOFFにした上で数値(0〜9)だけを許可する方法を紹介する。

この方法では前回のソースを再利用している。それというのも現在の列番号を取得するのに必要だからである。

普通のTextBoxコントロールであれば、通常のKeyPressイベント内で制御すれば良いのだが、DataGridViewでそれをやってもCell内のKeyPressイベントを拾ってはくれない。これはDataGridViewのセルにはTextBox・ComboBoxなどいくつものスタイルがあって、それぞれのタイプ別にイベントを持っているからである。

Private colNo, rowNo As Integer
'DataGridViewのTextBoxセルを宣言
Private TextEditCtrl As DataGridViewTextBoxEditingControl
 
'//// 列毎にIMEを制御 ///////
Private Sub DataGridView1_CellEnter(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) _
Handles DataGridView1.CellEnter
colNo = e.ColumnIndex '現在の列番号
rowNo = e.RowIndex '現在の行番号
Select Case e.ColumnIndex
Case 0, 4, 11
'この列は日本語入力ON
DataGridView1.ImeMode = Windows.Forms.ImeMode.Hiragana
Case 1 To 3, 5 To 10
'この列はIME無効(半角英数のみ)
DataGridView1.ImeMode = Windows.Forms.ImeMode.Disable
End Select
End Sub
 
'///// DataGridViewの編集コントロールが表示された時に //////
'///// KeyPressイベントを関連付け //////
Private Sub DataGridView1_EditingControlShowing( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) _
Handles DataGridView1.EditingControlShowing
TextEditCtrl = CType(e.Control, DataGridViewTextBoxEditingControl)
AddHandler TextEditCtrl.KeyPress, AddressOf TextEditCtrl_KeyPress
End Sub
 
'///// TextBoxセル内でのKeyPressイベント //////
Private Sub TextEditCtrl_KeyPress(ByVal sender As Object, _
ByVal e As KeyPressEventArgs)
Select Case colNo '現在の列番号
Case 2, 3, 6 '数値のみ許可
Select Case e.KeyChar
Case Chr(Keys.Back) 'BackSpace
Case Chr(Keys.D0) To Chr(Keys.D9) '数値キー
'テンキー用は不要(コメント参照)
'Case Chr(Keys.NumPad0) To Chr(Keys.NumPad9)
'小数点(.)を許可したい場合は
'Case Chr(Keys.Decimal) を追加
Case Else
'上記キー以外は処理しないようにする
'(Delete,Enter,Tabなどは有効)
e.Handled = True
End Select
End Select
End Sub
 
'////// 編集が終わったタイミングでKeyPressイベントの関連付けを解除 /////
Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) _
Handles DataGridView1.CellEndEdit
RemoveHandler TextEditCtrl.KeyPress, AddressOf TextEditCtrl_KeyPress
End Sub


posted by なっちゃん at 16:44| 静岡 ☁| Comment(10) | TrackBack(0) | VB.NET Tips | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
カラムの番号で制御するのもいいけど
カラムのデータタイプまたは名称で制御するようなサンプルの方がよくないかな。
そういうコードで嵌りかけたので。
Posted by ほいほい at 2006年09月29日 15:21
データバインドだったらその方が汎用的ですね。これらのTipsは開発中の覚書みたいなものなので、その時に必要なことしか扱わない傾向があります(^^;
Posted by なっちゃん at 2006年09月29日 15:44
Chr(Keys.NumPad0)からChr(Keys.NumPad9)までを出力してみて下さい。
この判定方法だと一部の文字が入力出来てしまいます・・・。
Posted by たまたま通った人 at 2006年10月17日 10:35
おお!確かに。
Keys.NumPadで判定するには KeyPressイベントではなく、KeyDownイベントでKey.Codeで判定すべきなんですね。ご指摘ありがとうございます。
今回の場合は、単純にChr(Keys.D0)〜Chr(Keys.D9)までを指定すればNumPadも両方判定してくれました。
Posted by なっちゃん at 2006年10月17日 11:15
「Keys.Decimal」はマッピング値が違うらしく、小数点として機能しません。("."cで回避)
Posted by mmot at 2007年01月15日 13:24
あれ、もしかして thinkPadだから「OemPeriod」か「Oemcomma」なのかな。
Posted by mmot at 2007年01月15日 14:33
参考にさせていただきました。ありがとうございます。

ところで、
DataGridView1_EditingControlShowing
のイベント内の処理ですが、このままだと毎回結び付けをしてしまうため、徐々に一度のKeyPressで大量のイベントが発生してしまうようになります。
If (TextEditCtrl Is Nothing) Then
TextEditCtrl = CType(e.Control, DataGridViewTextBoxEditingControl)
AddHandler TextEditCtrl.KeyPress, AddressOf TextEditCtrl_KeyPress
End If
等、一度だけ関連付けを行うようにしてないとまずいでね。
Posted by ぐ at 2008年01月28日 15:18
ですので、編集が終わったDataGridView1_CellEndEditイベント内でKeyPressイベントの関連付けを解除してますよ。
Posted by なっちゃん at 2008年01月29日 15:18
そうですね。
最後まで読んでいませんでした。
失礼しました。
Posted by ぐ at 2008年01月29日 15:45
自力ではとても実装できない内容をご教示いただき、お礼申し上げます。
DataGridView で Boolean の列(外観は CheckBox)があります。この列からの Leave 時に Null Reference 例外が発生してしまいます。どのようにすればよいかご教示頂ければ幸いです。
Posted by 北窓舎 at 2012年06月24日 16:31
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。