DataGridのKeyDownイベントを拾うには?

解決


のんの  2006-09-06 00:49:37  No: 133079

いつもお世話になっております。
DataGridのKeyDownイベントがうまく機能しないので

Private Sub t_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
  MessageBox.Show("キーボードの >が押されました")
End Sub

というメソッドを作り

Dim t As DataGridTextBoxColumn
For Each t In DataGrid1.TableStyles(0).GridColumnStyles
  AddHandlert.TextBox.KeyDown,NewKeyEventHandlerAddressOfMe.t_KeyDown)
Next

としましたがうまく機能しません。
よろしければアドバイスをおねがいします。


のんの  2006-09-06 01:03:38  No: 133080

すみません、間違いがありました。For Each・・・のところは↓です。
For Each t In DataGrid1.TableStyles(0).GridColumnStyles
AddHandler t.TextBox.KeyDown, New KeyEventHandler(AddressOf Me.t_KeyDown)
Next

と、あと開発環境はVB.NET2003です。よろしくお願いします。


特攻隊長まるるう  2006-09-06 01:38:17  No: 133081

多くの Tips を公開しているようなサイトで
http://dobon.net/vb/dotnet/datagrid/catchkeyevents.html
同じようなコードが公開されていて、動作確認が取れているから、
コードの使い方が悪いか、動作の解釈が悪いんだろうね。

ちなみに、こういったイベント系のデバッグで MessageBox は
使いません。理由は、処理が中断してしまうので、MessageBox を
表示しない時と動作が変わる事があるからです。
つまりデバッグの意味がありません。Debug.WriteLine などを
使ってください。

まず疑うのは DataGrid1.TableStyles の数。自分で DataGridTableStyle
を追加するようになると、データの表示更新などでも New() して
追加して。。。という無駄なインスタンス生成を繰り返して、
実際使っている DataGridTableStyle が DataGrid1.TableStyles(0)
でなく DataGrid1.TableStyles(1) だった。。。というのがあり得ます。
Count プロパティで確認してください。

ただ、
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200608/06080100.txt
でカラムのテキストが変更できているなら指定はあっていそう。。。

…となると、解釈が悪い?…それは本当にセル内でのキーイベント
ですか?
[VB.NET2003]
    Private Sub DataGrid1_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles DataGrid1.KeyDown
        Debug.WriteLine("DataGrid1のイベントで処理されているよ?")
    End Sub
…を追加して出力があったなら、セル内のキーイベントは起こらないはず
ですよね?

あとは、もしかしたらキーの種類によって動作が異なる特別なキーが
あるかもしれません。テストするキーを色々と変更してみてください。


のんの  2006-09-06 19:01:43  No: 133082

特攻隊長まるるう さんありがとうございます。
アドバイスやリンク先の内容を参考に
ソースを以下のように書き直しましたがまだKeyDownを拾うことができません。
アドバイスなどありましたらお願いします。

Private Sub Frm101_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
  Dim ts As DataGridTableStyle
  ts = DataGrid1.TableStyles(0)
  Dim cs As DataGridTextBoxColumn = _
       CType(ts.GridColumnStyles(0), DataGridTextBoxColumn)
  'TextBoxの取得
  Dim tb As TextBox = cs.TextBox
  'KeyDownイベントハンドラを追加()
  AddHandler tb.KeyDown, AddressOf Me.t_KeyDown
End Sub

Private Sub t_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
  Debug.WriteLine("キーが押された")
End Sub


特攻隊長まるるう  2006-09-06 20:54:36  No: 133083

いや、確認してくださいといった内容を、確認した結果を教えてくれないと
こっちでは分からないことだから。。。
こちらの環境では、幾つかのキーの動作確認は取れてます。やりかたが
悪いのでは?どう悪いのかは、前回の書き込みを参考にしてください。


のんの  2006-09-06 22:02:04  No: 133084

お世話になっております。
確認した結果ですが
Private Sub DataGrid1_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles DataGrid1.KeyDown
  Debug.WriteLine("DataGrid1のイベントで処理されているよ?")
End Sub
は通過しませんでした、
また、キーボード上のすべてのキーを押しても
Private Sub t_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
  Debug.WriteLine("キーが押された")
End Sub
を通過しませんでした。
尚、グリッド内で編集状態になっている時にセル内でキーを押しています。
これ以外に何か原因とかありますか?もしありましたら教えてください。


特攻隊長まるるう  2006-09-06 23:11:08  No: 133085

[VB.NET2003]
            Debug.WriteLine(Me.DataGrid1.TableStyles.Count)
の結果は1でしたか?


のんの  2006-09-07 01:23:38  No: 133086

はい。
Debug.WriteLine(Me.DataGrid1.TableStyles.Count)
の結果は1になります。


特攻隊長まるるう  2006-09-07 02:11:47  No: 133087

…だとしたら分からないですねぇ。

Load イベントでいきなり設定してるから、デザイン画面とか
データベース接続ウィザードとかを使って設定してるんだと
思うけど、ボクは普段使いませんから。。。

とりあえず新規プロジェクトを作成して、Form1 に DataGrid1
のみ貼り付けて、以下のコードを実行してみてください。
…出力はありますか?
[VB.NET2003]
    Private m_DataTable As DataTable

    ' テスト表示用
    Private Class SQLListCol
        Friend Const DT As String = "日付"
        Friend Const Col1 As String = "AA"
        Friend Const Col2 As String = "BB"
        Friend Const Col3 As String = "CC"
    End Class

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        With Me.DataGrid1
            .TableStyles.Add(New DataGridTableStyle)
            Call MakeDataTable()
            .DataSource = Me.m_DataTable
        End With

        Dim t As DataGridColumnStyle
        For Each t In Me.DataGrid1.TableStyles(0).GridColumnStyles
            If TypeOf t Is DataGridTextBoxColumn Then
                AddHandler DirectCast(t, DataGridTextBoxColumn).TextBox.KeyDown, New KeyEventHandler(AddressOf Me.t_KeyDown)
            End If
        Next
    End Sub

    Private Sub t_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
        Debug.WriteLine("キーボードの[" & e.KeyCode & "]が押されました")
    End Sub

    Private Sub DataGrid1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGrid1.KeyDown
        Debug.WriteLine("キーボードの[" & e.KeyCode & "]が DataGrid1 で処理されました")
    End Sub

    Private Sub MakeDataTable()
        Dim wColItem As DataColumn
        ' データグリッドに表示するデータテーブルの設定
        Me.m_DataTable = New DataTable
        ' カラムの設定
        With Me.m_DataTable
            wColItem = New DataColumn(SQLListCol.DT, Type.GetType("System.DateTime"))
            .Columns.Add(wColItem)
            wColItem = New DataColumn(SQLListCol.Col1, Type.GetType("System.Boolean"))
            .Columns.Add(wColItem)
            wColItem = New DataColumn(SQLListCol.Col2, Type.GetType("System.Single"))
            .Columns.Add(wColItem)
            wColItem = New DataColumn(SQLListCol.Col3, Type.GetType("System.Single"))
            .Columns.Add(wColItem)
        End With

        Dim wDataRow As System.Data.DataRow
        Dim wDate As New Date(2004, 5, 7, 11, 34, 0)
        For i As Integer = 0 To 14
            wDataRow = Me.m_DataTable.NewRow()
            wDataRow.Item(SQLListCol.DT) = wDate.AddDays(i)
            wDataRow.Item(SQLListCol.Col1) = i Mod 2
            wDataRow.Item(SQLListCol.Col2) = i + 0.02
            wDataRow.Item(SQLListCol.Col3) = i + 0.03
            Me.m_DataTable.Rows.Add(wDataRow)
        Next
    End Sub


のんの  2006-09-07 02:29:48  No: 133088

「キーボードの[80]が DataGrid1 で処理されました」
と表示されました。
(この時、グリッド内にデータは表示されていませんでした。)


のんの  2006-09-07 02:46:58  No: 133089

すみません。
特攻隊長まるるう さんのソースはうまく動きました。
このソースを参考によく研究したいと思います。


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加