実現したいこと
- DataGridViewのComboBox列を編集可能としたい
前提
DataGridViewにComboBox列を設け、入力済みの値から選択、もしくはユーザーが新しい項目を入力できるようにするため、dobon.netさんを参考にコードを組みました。
DataGridViewのコンボボックスにユーザーが文字列を入力できるようにする
また、Enter押下時に次のセルに移るようコードを組んでいます。
発生している問題・エラーメッセージ
該当ページのコメント欄にも書かれていますが、最終行のコンボボックスにて文字列入力→Enterを行うと入力内容が消えてしまい、コンボボックスには空文字列が追加されてしまいます。
(CellValidatingイベントにてFormattedValueが空となる)
該当のソースコード
VB.NET
1Public Class Form1 2 3 Private TEST_DATA As String() = { 4 "1,ABC,あいうえお", 5 "2,XYZ,かきくけこ", 6 "3,ABC,さしすせそ" 7 } 8 9 Private Sub Form1_Load(sender As Object, e As EventArgs) _ 10 Handles Me.Load 11 12 DataGridView1.AllowUserToAddRows = False 13 14 'コンボボックス列の取得 15 Dim cbc As DataGridViewComboBoxColumn = CType(DataGridView1.Columns(1), DataGridViewComboBoxColumn) 16 17 'データの設定 18 For Each str As String In TEST_DATA 19 Dim elem As String() = str.Split(","c) 20 21 If (Not cbc.Items.Contains(elem(1))) Then 22 'コンボボックスの項目に追加する 23 cbc.Items.Add(elem(1)) 24 End If 25 26 '行の追加 27 Dim index As Integer = DataGridView1.Rows.Add() 28 29 For i = 0 To 2 30 DataGridView1.Rows(index).Cells(i).Value = elem(i) 31 Next 32 Next 33 34 '空行を追加 35 DataGridView1.Rows.Add() 36 37 End Sub 38 39 '----------------------------------------------------------------- 40 ' Enterにて次のセルに進めるようにするための処理 41 ' https://dobon.net/vb/dotnet/datagridview/enterkeymoveright.html 42 '----------------------------------------------------------------- 43 Private Sub DataGridView1_KeyDown(sender As Object, e As KeyEventArgs) _ 44 Handles DataGridView1.KeyDown 45 Dim dgv As DataGridView = CType(sender, DataGridView) 46 47 If (e.KeyCode = Keys.Enter) Then 48 49 If (dgv.CurrentCellAddress.X = dgv.ColumnCount - 1) AndAlso 50 (dgv.CurrentCellAddress.Y = dgv.RowCount - 1) Then 51 '最終行最終列の場合は、何もしない(最終行最終列で 52 'Tabキーを送信すると、次のコントロールにフォーカスが移動) 53 Return 54 End If 55 56 'Tabキーを送信する 57 SendKeys.Send("{TAB}") 58 59 'フォーカスが下に移動しないようにする 60 e.Handled = True 61 End If 62 63 End Sub 64 65 Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) _ 66 Handles DataGridView1.CellEndEdit 67 Dim dgv As DataGridView = CType(sender, DataGridView) 68 69 '最終行最終列の場合は、何もしない 70 If (e.ColumnIndex = dgv.ColumnCount - 1) AndAlso 71 (e.RowIndex = dgv.RowCount - 1) Then 72 Return 73 End If 74 75 '最終行以外では、フォーカスを上に移動 76 '(最終行以外では、編集後、フォーカスが下に移動するため) 77 If (e.RowIndex < dgv.RowCount - 1) Then 78 SendKeys.Send("{UP}") 79 End If 80 81 'Tabキーを送信する 82 SendKeys.Send("{TAB}") 83 84 End Sub 85 86 '----------------------------------------------------------------- 87 ' コンボボックスにテキスト入力できるようにするための処理 88 ' https://dobon.net/vb/dotnet/datagridview/comboboxdropdownstyle.html 89 '----------------------------------------------------------------- 90 Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) _ 91 Handles DataGridView1.EditingControlShowing 92 Dim dgv As DataGridView = CType(sender, DataGridView) 93 94 If (TypeOf e.Control Is DataGridViewComboBoxEditingControl) Then 95 '該当する列か調べる 96 If (dgv.CurrentCell.OwningColumn.Name = "Column2") Then 97 '編集のために表示されているコントロールを取得 98 Dim cb As DataGridViewComboBoxEditingControl = CType(e.Control, DataGridViewComboBoxEditingControl) 99 cb.DropDownStyle = ComboBoxStyle.DropDown 100 101 'イベントハンドラを削除 102 RemoveHandler cb.KeyPress, AddressOf DataGridViewComboBox_KeyPress 103 104 'KeyPressイベントハンドラを追加 105 AddHandler cb.KeyPress, AddressOf DataGridViewComboBox_KeyPress 106 End If 107 End If 108 109 End Sub 110 111 Private Sub DataGridView1_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs) _ 112 Handles DataGridView1.CellValidating 113 Dim dgv As DataGridView = CType(sender, DataGridView) 114 115 '該当する列か調べる 116 If (dgv.Columns(e.ColumnIndex).Name = "Column2") AndAlso 117 (TypeOf dgv.Columns(e.ColumnIndex) Is DataGridViewComboBoxColumn) Then 118 Dim cbc As DataGridViewComboBoxColumn = CType(dgv.Columns(e.ColumnIndex), DataGridViewComboBoxColumn) 119 120 'コンボボックスの項目に追加する 121 If Not cbc.Items.Contains(e.FormattedValue) Then 122 cbc.Items.Add(e.FormattedValue) 123 End If 124 125 'セルの値を設定しないと、元に戻ってしまう 126 dgv(e.ColumnIndex, e.RowIndex).Value = e.FormattedValue 127 End If 128 129 End Sub 130 131 Private Sub DataGridViewComboBox_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) 132 Dim cb As DataGridViewComboBoxEditingControl = CType(sender, DataGridViewComboBoxEditingControl) 133 134 If (DataGridView1.CurrentCell.OwningColumn.Name = "Column2") AndAlso 135 (TypeOf DataGridView1.CurrentCell.OwningColumn Is DataGridViewComboBoxColumn) Then 136 cb.DroppedDown = False 137 End If 138 139 End Sub 140 141End Class
試したこと
コメント欄を参考にKeyPressイベントにてDroppedDown = Falseを設定するようにしましたが、解決しませんでした。(デバッガにてイベントが上がってきていることは確認できました)
また、Enter入力時にTABキーを送信するロジックが悪さしているかもしれないと考え、該当イベント処理をコメントアウトしましたが、結果は変わりませんでした。
なお、EnterキーでなくTABキーにて編集を終了した場合はうまくいきます。
補足情報(FW/ツールのバージョンなど)
開発環境
Visual Studio 2015 Version 14.0.25431.01 Update 3
Microsoft .NET Framework Version 4.8.04084
よろしくお願いいたします。

回答2件
あなたの回答
tips
プレビュー