DataGridViewでEnterキーが押された時に横のセルに移動したい
ちょっと苦手なDataGridViewのメモ
CellEnterイベントとかでEnterキーの時はTabキーを送るようにしていたんだけど
ReadOnlyのセルはとばしたかったり、最終行がReadOnlyだったらとか
制御が面倒になってきて、結局DataGridViewを継承したカスタムコントロールを作るのが一番手っ取り早かったので。
あちこち参考にさせていただき、今はこれに落ち着きました。
今回のバグはこれで何とかなりそう~。たぶん
*******
Enterキーでフォーカス横移動
ReadOnly=Trueのセルは飛ばす
最終列がReadOnlyの場合は次の行へ移動
最終行だった場合は最初の行に戻る
********
'/////////////////// ' DataGridView '/////////////////// ''' <summary> ''' DataGridView ''' Enterキーが押された時に、Tabキーが押されたのと同じ動作をする ''' (現在のセルを隣のセルに移動する) ''' ReadOnlyのセルはとばす ''' </summary> Public Class DataGridViewEx Inherits DataGridView Protected Overrides Function ProcessDialogKey(ByVal keyData As Keys) As Boolean If (keyData And Keys.KeyCode) = Keys.Tab OrElse (keyData And Keys.KeyCode) = Keys.Enter Then '現在のセルの次の列 Dim col As Integer = Me.CurrentCell.ColumnIndex + 1 While col < Me.Columns.Count If Not Me.Rows(Me.CurrentCell.RowIndex).Cells(col).ReadOnly And Me.Rows(Me.CurrentCell.RowIndex).Cells(col).Visible Then Exit While End If col = col + 1 End While If col < Me.Columns.Count Then Me.CurrentCell = Me.Rows(Me.CurrentCell.RowIndex).Cells(col) Else '行 Dim row As Integer = Me.CurrentCell.RowIndex + 1 Dim Flg As Boolean = False '無限ループ防止フラグ If row = Me.Rows.Count Then '最終行の場合は最初の行に戻す row = 0 Flg = True End If While row < Me.Rows.Count For col = 0 To Me.Columns.Count - 1 If Not Me.Rows(row).Cells(col).ReadOnly And Me.Rows(row).Cells(col).Visible Then Exit While End If Next If row = Me.Rows.Count - 1 And Flg = False Then '1回だけ最初の行に戻す row = 0 Flg = True Else row = row + 1 End If End While If col < Me.Columns.Count Then Me.CurrentCell = Me.Rows(row).Cells(col) End If End If Return True End If Return MyBase.ProcessDialogKey(keyData) End Function Protected Overrides Function ProcessDataGridViewKey(ByVal e As KeyEventArgs) As Boolean If e.KeyData = Keys.Tab OrElse e.KeyData = Keys.Enter Then Dim col As Integer = Me.CurrentCell.ColumnIndex + 1 While col < Me.Columns.Count If Not Me.Rows(Me.CurrentCell.RowIndex).Cells(col).ReadOnly And Me.Rows(Me.CurrentCell.RowIndex).Cells(col).Visible Then Exit While End If col = col + 1 End While If col < Me.Columns.Count Then Me.CurrentCell = Me.Rows(Me.CurrentCell.RowIndex).Cells(col) Else '行 Dim row As Integer = Me.CurrentCell.RowIndex + 1 Dim Flg As Boolean = False '無限ループ防止フラグ If row = Me.Rows.Count Then '最終行の場合は最初の行に戻す row = 0 Flg = True End If While row < Me.Rows.Count For col = 0 To Me.Columns.Count - 1 If Not Me.Rows(row).Cells(col).ReadOnly And Me.Rows(row).Cells(col).Visible Then Exit While End If Next If row = Me.Rows.Count - 1 And Flg = False Then '1回だけ最初の行に戻す row = 0 Flg = True Else row = row + 1 End If End While If col < Me.Columns.Count Then Me.CurrentCell = Me.Rows(row).Cells(col) End If End If Return True End If Return MyBase.ProcessDataGridViewKey(e) End Function End Class