- PR -

◆DataGridView でKeyDownイベントを捕捉したい。

投稿者投稿内容
One.net
大ベテラン
会議室デビュー日: 2008/03/01
投稿数: 202
投稿日時: 2008-08-13 11:46
WindowsXP、VB2005EE Access2003 でWindowsアプリケーションを開発中です。
商品マスターからバインドしたDataGridView の各行の数量列に数量を入力するたびに
KeyDownイベントハンドラのEnterキーで次のような計算集計させたいのですが
KeyDownイベントハンドラがうまく動作しません。
金額列 = 単価列 × 数量列

以前、次のようなKeyPressイベントのコードを使ってうまく動作しましたのでKeyPressをKeyDown
に変更して使いましたが「dataGridViewTextBox_KeyDownは宣言されていない」とエラーが出ます。
コード:

'---EditingControlShowingイベントハンドラ
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, _
ByVal e As DataGridViewEditingControlShowingEventArgs) _
Handles DataGridView1.EditingControlShowing
'--このがDataGridViewTextBoxEditingControlであれば
If TypeOf e.Control Is DataGridViewTextBoxEditingControl Then
Dim dgv As DataGridView = CType(sender, DataGridView)
'---編集のために表示されているコントロールを取得
Dim tb As DataGridViewTextBoxEditingControl = _
CType(e.Control, DataGridViewTextBoxEditingControl)
'------------イベントハンドラを削除
RemoveHandler tb.KeyPress, AddressOf dataGridViewTextBox_KeyPress
'-キーイベントを発生させたい列であれば
If dgv.CurrentCell.OwningColumn.Name = _
"DataGridViewTextBoxColumn8" Then
'---KeyPressイベントハンドラを追加
AddHandler tb.KeyPress, AddressOf dataGridViewTextBox_KeyPress
End If
End If
End Sub


'DataGridViewに表示されているテキストボックスのKeyPressイベントハンドラ
Private Sub dataGridViewTextBox_KeyPress(ByVal sender As Object, _
ByVal e As KeyPressEventArgs) Handles DataGridView1.KeyPress
If e.KeyChar < "0"c Or e.KeyChar > "9"c Then
e.Handled = True '--数字しか入力できないようにする
End If
End Sub



また次のサイトを見つけましたがC#で記載されていて読み取れません。
http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=861305&SiteID=7

DataGridView で編集中のセルでKeyDownイベントを捕捉する方法をご指導下さい。

修正:URLを追加記述

[ メッセージ編集済み 編集者: One.net 編集日時 2008-08-13 11:59 ]
One.net
大ベテラン
会議室デビュー日: 2008/03/01
投稿数: 202
投稿日時: 2008-08-13 12:38
自己回答
質問を投稿してから、関連サイトを捜していると次の参考になるサイトが見つかりました。
http://dobon.net/vb/dotnet/datagridview/enterkeymoveright.html
このサイトを勉強しようと思います。
ご迷惑をおかけしました。
One.net
大ベテラン
会議室デビュー日: 2008/03/01
投稿数: 202
投稿日時: 2008-08-13 14:00
下のサイトはDataGridViewでEnterキーを押すと隣のセルにフォーカスが移動されるようにする
専用のDataGridViewクラスの派生クラスを作成を作成する方法でした。
http://dobon.net/vb/dotnet/datagridview/enterkeymoveright.html

DataGridView で編集中のセルでKeyDownイベントを捕捉するにはどのようにすればよいのか
よろしくご指導下さい。

[ メッセージ編集済み 編集者: One.net 編集日時 2008-08-13 14:01 ]
Toshi
ベテラン
会議室デビュー日: 2007/09/18
投稿数: 68
お住まい・勤務地: 関東のどっか
投稿日時: 2008-08-13 14:45
こんにちわ

KeyDownにこだわっている理由はありますか?
もしなければ、PreviewKeyDownイベントを利用するのも手かと

以上、参考になれば幸いです。
One.net
大ベテラン
会議室デビュー日: 2008/03/01
投稿数: 202
投稿日時: 2008-08-13 15:10
Toshiさん、ご指導ありがとうございます。
KeyDownにこだわる理由などありません。ただPreviewKeyDownイベントを知らなかっただけです。
早速調べると「このコントロールにフォーカスがあるときにキーが押された場合KeyDown イベントの
前に発生します。」
とあり、また以下のような .NET Tips を見つけました。
http://dobon.net/vb/dotnet/control/btndetectarraykey.html

ところで、次のことを教えてください。
1.PreviewKeyDownはDataGridViewの編集中のセルでもで使用できるのでしょうか
2.下記のコードの中に「Button1」とありますが、何かのボタンが必要なのでしょうか。
コード:

'PreviewKeyDownイベントハンドラ
Private Sub Button1_PreviewKeyDown(ByVal sender As Object, _
ByVal e As PreviewKeyDownEventArgs) _
Handles Button1.PreviewKeyDown
Select Case e.KeyCode
'矢印キーが押されたことを表示する
Case Keys.Up, Keys.Left, Keys.Right, Keys.Down
Console.WriteLine("矢印キーが押されました。")
'Tabキーが押されてもフォーカスが移動しないようにする
Case Keys.Tab
e.IsInputKey = True
End Select
End Sub


Toshiさん、単に知らないだけで、昨日から悩んで色々模索していました。
大変助かりました。ありがとうございました。


修正:「Button1」についての質問を追加
追加修正:ところで、次のことを教えてください。を追加


[ メッセージ編集済み 編集者: One.net 編集日時 2008-08-13 15:17 ]

[ メッセージ編集済み 編集者: One.net 編集日時 2008-08-13 20:21 ]
とーちゃん
会議室デビュー日: 2008/07/08
投稿数: 11
投稿日時: 2008-08-14 00:28
ええと、、恐らく解決していないかなと思ったので、One.netさんが最初に提示されたソースに手を加えてみました。これで"DataGridViewTextBoxColumn8"という名前のついた列にあるセルのKeyDownイベントが拾えるようになるかと思います。

と、答えを提示してしまう前に、4点ほどご自身で勉強してみていただきたいことがあります。
1.「EditingControlShowing」とはどういう条件下で発生するイベントなのか。
2.「RemoveHandler 〜 AddressOf」とはどんな働きをするのでしょう?
3.「AddHandler 〜 AddressOf」とはどんな働きをするのでしょう?
4.上記3つを確認した上で、自分がセル上でボタンを押したときに、どのようなことが起きているのか、ステップイン機能を利用して、1行1行、順を追って確認し理解するように勤めてみてください。

コード:

'---EditingControlShowingイベントハンドラ
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, _
ByVal e As DataGridViewEditingControlShowingEventArgs) _
Handles DataGridView1.EditingControlShowing
'--このがDataGridViewTextBoxEditingControlであれば
If TypeOf e.Control Is DataGridViewTextBoxEditingControl Then
Dim dgv As DataGridView = CType(sender, DataGridView)
'---編集のために表示されているコントロールを取得
Dim tb As DataGridViewTextBoxEditingControl = _
CType(e.Control, DataGridViewTextBoxEditingControl)
'------------イベントハンドラを削除
RemoveHandler tb.KeyDown, AddressOf dataGridViewTextBox_KeyDown
'-キーイベントを発生させたい列であれば
If dgv.CurrentCell.OwningColumn.Name = _
"DataGridViewTextBoxColumn8" Then
'---KeyDownイベントハンドラを追加
AddHandler tb.KeyDown, AddressOf dataGridViewTextBox_KeyDown
End If
End If
End Sub

'DataGridViewに表示されているテキストボックスのKeyDownイベントハンドラ
Private Sub dataGridViewTextBox_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
If e.KeyCode < "0" Or e.KeyCode > "9" Then
e.Handled = True '--数字しか入力できないようにする
End If
End Sub


最後にこちらの件ですが、
1.PreviewKeyDownはDataGridViewの編集中のセルでもで使用できるのでしょうか
  上記コードをPreviewKeyDownを拾えるように書き換えることで使用できました。

2.下記のコードの中に「Button1」とありますが、何かのボタンが必要なのでしょうか。
  ご覧になられたDOBON.NETさんのTipsはボタンコントロールのPreviewKeyDownイベントを取得するというものです。そのため、ソースにButton1と記載されてるのではないでしょうか。


[ メッセージ編集済み 編集者: とーちゃん 編集日時 2008-08-14 00:50 ]
One.net
大ベテラン
会議室デビュー日: 2008/03/01
投稿数: 202
投稿日時: 2008-08-14 06:16
とーちゃんさん、ご丁寧ななご指導をいただき本当にありがとうございます。
早速提示いただきましたコードをテストする前に次の4点について調べました。
閲覧者のためにその結果を掲載します。

1.「EditingControlShowing」とはどういう条件下で発生するイベントなのか。
調査結果→DataGridViewの編集中(数字や文字を入力始めると)はテキストボックスが
使用されているため、DataGridViewのキーイベントを補足するのではなく、このテキス
トボックスのキーイベントを捕捉する必要があるます。
そしてこのテキストボックスが表示された時は、EditingControlShowingイベントが発生
し、このイベントハンドラで各種の処理設定を行います。詳細は下を見てください。
http://dobon.net/vb/dotnet/datagridview/textboxevent.html

2.「RemoveHandler 〜 AddressOf」とはどんな働きをするのでしょう?
同じイベントハンドラが同じコントロールのイベントに何回も追加されないように
する必要があり、イベントを無効化するためにイベントハンドラを削除します。詳細は下を見てください。
http://dobon.net/vb/bbs/log3-5/2589.html

3.「AddHandler 〜 AddressOf」とはどんな働きをするのでしょう?
調査結果→捕捉したいイベントハンドラを追加します。

4.上記3つを確認した上で、自分がセル上でボタンを押したときに、どのようなことが起きて
いるのか、ステップイン機能を利用して、1行1行、順を追って確認し理解するように勤めて
みてください。
このことはまだ試していませんが、とりあえずお礼を言いたくて 投稿しました。
とーちゃんさんのご指摘の通り、PreviewKeyDownイベントではDataGridViewのセルが
編集中の場合は、捕捉してくれませんでした。
これからご提示いただきましたコードを試してみます。本当にありがとうございました。

One.net
大ベテラン
会議室デビュー日: 2008/03/01
投稿数: 202
投稿日時: 2008-08-14 06:40
とーちゃんさん
その後、ご提示いただきましたコードを試してみましたところ以下の部分に次のようなエラーが出ます。
エラー内容→「名前"dataGridViewTextBox_KeyDown"は定義されていません」
発生場所1→RemoveHandler tb.KeyDown, AddressOf dataGridViewTextBox_KeyDown
発生場所2→AddHandler tb.KeyDown, AddressOf dataGridViewTextBox_KeyDown

追加部分
次の部分にもエラーが出ます。
エラー内容→「"e.KeyCode"は"System.Windows.Forms.KeyEventArgs"のメンバーではありません。」
発生場所1→If e.KeyCode < "0" Or e.KeyCode > "9" Then
この部分は次のように変更したいと思っていますが
コード:

Select Case e.KeyCode
Case Keys.Enter
計算() '---計算モジュールへ
End Select



このエラーに対する処理方法をよろしくご指導下さい。

修正:「追加部分」以降を追加しました。


[ メッセージ編集済み 編集者: One.net 編集日時 2008-08-14 06:52 ]

スキルアップ/キャリアアップ(JOB@IT)