DataGridViewのカーソル制御
投稿日: 2012-09-13 /
カテゴリー:job
ええと、VB2010のDataGridViewで矢印キーとかEnterキーとかTabキーでカーソル移動をさせたいなーと思って苦戦したのでメモ。
非表示や入力不可のセルを飛ばして移動します。端のセルの場合は前の行または次の行に移動します。
Shift+TabはTabと逆に移動します。
※Form内に以下を記述して、そのFormのDataGridViewのテキストの列にはmyDataGridViewTextBoxColumnを使用します。
Friend Class myDataGridViewTextBoxColumn Inherits DataGridViewTextBoxColumn Public Overrides Property CellTemplate() As System.Windows.Forms.DataGridViewCell Get Return New myDataGridViewTextBoxCell End Get Set(ByVal value As System.Windows.Forms.DataGridViewCell) MyBase.CellTemplate = value End Set End Property End Class Friend Class myDataGridViewTextBoxCell Inherits DataGridViewTextBoxCell Public Overrides ReadOnly Property EditType() As System.Type Get Return GetType(myDataGridViewTextBoxEditingControl) End Get End Property End Class Friend Class myDataGridViewTextBoxEditingControl Inherits DataGridViewTextBoxEditingControl Private Enum MoveTo None = 0 PrevCell = -1 NextCell = 1 End Enum Protected Overrides Sub OnPreviewKeyDown(e As PreviewKeyDownEventArgs) Select Case e.KeyCode Case Keys.Enter, Keys.Tab ' EnterキーとTabキーをEditingControlWantsInputKey()で拾えるようにする e.IsInputKey = True Case Else Call MyBase.OnPreviewKeyDown(e) End Select End Sub Public Overrides Function EditingControlWantsInputKey(ByVal keyData As System.Windows.Forms.Keys, _ ByVal dataGridViewWantsInputKey As Boolean) As Boolean Select Case keyData Case Keys.Left, Keys.Right, Keys.Enter, Keys.Tab, (Keys.Shift Or Keys.Tab) ' カーソル移動キーの押下時処理(左右・Enter・Tab) Dim intMove As MoveTo = MoveTo.None Dim blnWk As Boolean = False Select Case keyData Case Keys.Enter, Keys.Tab intMove = MoveTo.NextCell Case (Keys.Shift Or Keys.Tab) intMove = MoveTo.PrevCell Case Keys.Left If Me.SelectionStart = 0 Then blnWk = True If Me.SelectionLength = Me.Text.Length Then blnWk = True If blnWk = True Then intMove = MoveTo.PrevCell End If Case Keys.Right If Me.SelectionStart = Me.Text.Length Then blnWk = True If Me.SelectionLength = Me.Text.Length Then blnWk = True If blnWk = True Then intMove = MoveTo.NextCell End If End Select If intMove <> MoveTo.None Then Dim grid As DataGridView = Me.EditingControlDataGridView Call Me.SetFocusNextCell(grid, intMove) End If Return True Case Else Return MyBase.EditingControlWantsInputKey(keyData, dataGridViewWantsInputKey) End Select End Function Private Sub SetFocusNextCell(ByVal grid As DataGridView, ByVal intMove As MoveTo) With grid Dim col As Integer = .CurrentCellAddress.X Dim row As Integer = .CurrentCellAddress.Y Dim r As Integer = row Dim c As Integer Dim blnWk As Boolean Dim nextRow As Integer = -1 Dim nextCol As Integer = -1 Dim sc As Integer Dim maxrow As Integer Dim ccnt As Integer = .ColumnCount Dim rcnt As Integer = .RowCount ' 直近の有効なセルにカーソルを移動させる Select Case intMove Case MoveTo.PrevCell maxrow = row - 1 If maxrow < 0 Then maxrow = row For r = row To maxrow Step -1 sc = col - 1 If r < row Then sc = ccnt - 1 For c = sc To 0 Step -1 blnWk = True ' 適当にチェック(VisibleとかReadOnlyとか) If blnWk = True Then nextRow = r nextCol = c Exit For End If Next c If nextRow >= 0 Then Exit For Next r Case MoveTo.NextCell maxrow = row + 1 If maxrow >= rcnt Then maxrow = row For r = row To maxrow sc = col + 1 If r > row Then sc = 0 For c = sc To ccnt - 1 blnWk = True ' 適当にチェック(VisibleとかReadOnlyとか) If blnWk = True Then nextRow = r nextCol = c Exit For End If Next c If nextRow >= 0 Then Exit For Next r End Select If nextRow >= 0 And nextCol >= 0 Then .CurrentCell = .Rows(nextRow).Cells(nextCol) End If End With End Sub End Class
この辺を参考にさしてもらいました。多謝。
http://dobon.net/vb/bbs/log3-42/25144.html
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=41202&forum=7
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=47305&forum=7
http://social.msdn.microsoft.com/Forums/ja/vbexpressja/thread/fc1a0d8d-23d1-4a4e-a88c-f9a1edd81cff
http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/234162d6-b3a6-4839-80b1-06641216f458