none
DataGridViewのコンボボックスに文字列を入力して「Enter」キーで確定すると空白になってしまいます。 RRS feed

  • 質問

  • お世話になります。

    OSは、「Vista」言語は、「VB2010Express」を使用しています。

    DataGridViewのコンボボックスに文字列を入力できるプログラムを作成しました。
    EditingControlShowingで、DropDownStyleプロパティでDropDownに変更してます。
    CellValidatingで、入力した値をコンボボックスに追加しています。
    CellEnterで、IMEをONにして、ドロップダウンリストを表示するようにしました。
    文字の入力して、「Enter」キーで確定すると、入力した文字が消えてしまいます。
    「左」「右」キー、またはマウスでセルを移動した場合には、文字が確定できました。

    「Enter」キーでも文字を確定できるようにする方法をご教示願えないでしょうか。
    CellEnterのダウンリスト表示処理を消去すると「Enter」キーでも確定できたのですが、
    コンボボックスを1回のクリックで表示できる機能は残したいので、よろしくお願いします。

    Public Class Form1

        Private _Ds As New DataSet
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim dt As DataTable
            dt = _Ds.Tables.Add("住所")
            dt.Columns.Add("県", GetType(System.String))
            dt.Columns.Add("住所", GetType(System.String))
            dt.Rows.Add("あ県", "あ市")
            dt.Rows.Add("い県", "い市")
            dt.Rows.Add("う県", "う市")

            Me.DataGridView1.DataSource = dt

            Dim ColKen As New DataGridViewComboBoxColumn
            ColKen.DataPropertyName = "県"
            ColKen.Name = "県Combo"
            ColKen.ValueMember = "県"
            ColKen.DisplayMember = "県"
            ColKen.HeaderText = "県"

            ColKen.Items.Add("あ県")
            ColKen.Items.Add("い県")
            ColKen.Items.Add("う県")
            DataGridView1.Columns.Insert(DataGridView1.Columns("住所").Index, ColKen)

        End Sub

        Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter
            With CType(sender, DataGridView)
                'コンボボックスの入力モードを全角にする。
                If .Columns(e.ColumnIndex).Name = "県Combo" Then
                    .ImeMode = Windows.Forms.ImeMode.On
                Else
                    .ImeMode = Windows.Forms.ImeMode.Off
                End If
                'コンボボックス選択されたら、ダウンリストをすぐに表示する
                If .Columns(e.ColumnIndex).Name = "県Combo" AndAlso _
                    TypeOf .Columns(e.ColumnIndex) Is DataGridViewComboBoxColumn Then
                    SendKeys.Send("{F4}")
                End If
            End With
        End Sub

        Private Sub DataGridView1_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating
            With CType(sender, DataGridView)
                If .CurrentCell.OwningColumn.Name = "県Combo" AndAlso _
                    TypeOf .Columns(e.ColumnIndex) Is DataGridViewComboBoxColumn Then

                    Dim cbc As DataGridViewComboBoxColumn = _
                        CType(.Columns(e.ColumnIndex), DataGridViewComboBoxColumn)

                    Dim sWork As String
                    sWork = e.FormattedValue.ToString
                    If Not cbc.Items.Contains(sWork) Then
                        'コンボボックスに入力した新しい文字列を追加する
                        cbc.Items.Add(sWork)
                    End If
                    CType(sender, DataGridView)(e.ColumnIndex, e.RowIndex).Value = sWork
                End If
            End With
        End Sub

        Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
            With CType(sender, DataGridView)
                If TypeOf e.Control Is DataGridViewComboBoxEditingControl Then
                    If .CurrentCell.OwningColumn.Name = "県Combo" Then
                        Dim cb As DataGridViewComboBoxEditingControl = _
                            CType(e.Control, DataGridViewComboBoxEditingControl)
                        'コンボボックスを編集可能にする。
                        cb.DropDownStyle = ComboBoxStyle.DropDown
                    End If
                End If
            End With
        End Sub
    End Class

    以上のプログラムで、あ県と表示されているコンボボックスで「え県」と入力して、
    「Enter」キーで確定すると空白になりました。

    よろしくお願いします。

     

    2010年12月3日 5:00

回答

  • EditingControlのコンボボックスのドロップダウンが表示されていて、

    選択されているアイテムが無い場合に、確定後セルの値が空白になるようです。

    ドロップダウンが表示されていない状態であれば、リストに値があるなし関係なく確定できるようです。


    入力値がドロップダウンリストになければドロップダウンを閉じ、あれば開くという

    制御を入れてみてはどうでしょうか。

    以下サンプルを書きますが、これ以外にも恐らく色々考慮すべき箇所があると思われるので

    あくまで参考として見てください。

     

    ※なお、上に載っているソースがベースで、差分のみです。

    Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
      With CType(sender, DataGridView)
        If TypeOf e.Control Is DataGridViewComboBoxEditingControl Then
          If .CurrentCell.OwningColumn.Name = "県Combo" Then
            Dim cb As DataGridViewComboBoxEditingControl = _
            CType(e.Control, DataGridViewComboBoxEditingControl)
            'コンボボックスを編集可能にする。
            cb.DropDownStyle = ComboBoxStyle.DropDown
            ' ■以下追加
            AddHandler e.Control.TextChanged, AddressOf EditCtrlTextChanged
          End If
        End If
      End With
    End Sub
    
    Private Sub EditCtrlTextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.TextChanged
      Dim ctrl As ComboBox = sender
      Dim hoge = From r In ctrl.Items Where r.ToString().IndexOf(ctrl.Text) = 0 Select r
      If ctrl.SelectedItem <> Nothing Then
        If ctrl.SelectedItem.ToString().Equals(ctrl.Text) Then
          Return
        End If
      End If
      If hoge.Count() > 0 Then
        If ctrl.DroppedDown <> True Then
          ctrl.DroppedDown = True
        End If
      Else
        If ctrl.DroppedDown = True Then
          ctrl.DroppedDown = False
        End If
      End If
    End Sub
    
    

    • 回答としてマーク 山本春海 2010年12月17日 7:53
    2010年12月6日 5:59
  • >honefai様

    ご教示ありがとうございます。
    ご教示いただいた内容を元に、検証をした結果、入力を開始した時点で
    ドロップダウンリストを閉じるように動作変更しました。

    ドロップダウンリストに入力した文字列があった場合に確定後、
    先頭1文字目が消えてしまう場合があったので、KeyPressにも
    ドロップダウンリストを閉じるように処理を追加しました。

        Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
            With CType(sender, DataGridView)
                If TypeOf e.Control Is DataGridViewComboBoxEditingControl Then
                    If .CurrentCell.OwningColumn.Name = "県Combo" Then
                        Dim cb As DataGridViewComboBoxEditingControl = _
                            CType(e.Control, DataGridViewComboBoxEditingControl)
                        'コンボボックスを編集可能にする。
                        cb.DropDownStyle = ComboBoxStyle.DropDown
                        ' ■以下追加
                        AddHandler e.Control.TextChanged, AddressOf EditCtrlTextChanged
                        AddHandler e.Control.KeyPress, AddressOf EditCtrlTextKeypress
                    End If
                End If
            End With
        End Sub

       Private Sub EditCtrlTextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
            Dim ctrl As ComboBox = sender
            ctrl.DroppedDown = False
        End Sub

        Private Sub EditCtrlTextKeypress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
            Dim ctrl As ComboBox = sender
            ctrl.DroppedDown = False
        End Sub


    ありがとうございます。大変参考になりました。

    • 回答としてマーク 山本春海 2010年12月17日 7:53
    2010年12月7日 6:27

すべての返信

  • EditingControlのコンボボックスのドロップダウンが表示されていて、

    選択されているアイテムが無い場合に、確定後セルの値が空白になるようです。

    ドロップダウンが表示されていない状態であれば、リストに値があるなし関係なく確定できるようです。


    入力値がドロップダウンリストになければドロップダウンを閉じ、あれば開くという

    制御を入れてみてはどうでしょうか。

    以下サンプルを書きますが、これ以外にも恐らく色々考慮すべき箇所があると思われるので

    あくまで参考として見てください。

     

    ※なお、上に載っているソースがベースで、差分のみです。

    Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
      With CType(sender, DataGridView)
        If TypeOf e.Control Is DataGridViewComboBoxEditingControl Then
          If .CurrentCell.OwningColumn.Name = "県Combo" Then
            Dim cb As DataGridViewComboBoxEditingControl = _
            CType(e.Control, DataGridViewComboBoxEditingControl)
            'コンボボックスを編集可能にする。
            cb.DropDownStyle = ComboBoxStyle.DropDown
            ' ■以下追加
            AddHandler e.Control.TextChanged, AddressOf EditCtrlTextChanged
          End If
        End If
      End With
    End Sub
    
    Private Sub EditCtrlTextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.TextChanged
      Dim ctrl As ComboBox = sender
      Dim hoge = From r In ctrl.Items Where r.ToString().IndexOf(ctrl.Text) = 0 Select r
      If ctrl.SelectedItem <> Nothing Then
        If ctrl.SelectedItem.ToString().Equals(ctrl.Text) Then
          Return
        End If
      End If
      If hoge.Count() > 0 Then
        If ctrl.DroppedDown <> True Then
          ctrl.DroppedDown = True
        End If
      Else
        If ctrl.DroppedDown = True Then
          ctrl.DroppedDown = False
        End If
      End If
    End Sub
    
    

    • 回答としてマーク 山本春海 2010年12月17日 7:53
    2010年12月6日 5:59
  • >honefai様

    ご教示ありがとうございます。
    ご教示いただいた内容を元に、検証をした結果、入力を開始した時点で
    ドロップダウンリストを閉じるように動作変更しました。

    ドロップダウンリストに入力した文字列があった場合に確定後、
    先頭1文字目が消えてしまう場合があったので、KeyPressにも
    ドロップダウンリストを閉じるように処理を追加しました。

        Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
            With CType(sender, DataGridView)
                If TypeOf e.Control Is DataGridViewComboBoxEditingControl Then
                    If .CurrentCell.OwningColumn.Name = "県Combo" Then
                        Dim cb As DataGridViewComboBoxEditingControl = _
                            CType(e.Control, DataGridViewComboBoxEditingControl)
                        'コンボボックスを編集可能にする。
                        cb.DropDownStyle = ComboBoxStyle.DropDown
                        ' ■以下追加
                        AddHandler e.Control.TextChanged, AddressOf EditCtrlTextChanged
                        AddHandler e.Control.KeyPress, AddressOf EditCtrlTextKeypress
                    End If
                End If
            End With
        End Sub

       Private Sub EditCtrlTextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
            Dim ctrl As ComboBox = sender
            ctrl.DroppedDown = False
        End Sub

        Private Sub EditCtrlTextKeypress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
            Dim ctrl As ComboBox = sender
            ctrl.DroppedDown = False
        End Sub


    ありがとうございます。大変参考になりました。

    • 回答としてマーク 山本春海 2010年12月17日 7:53
    2010年12月7日 6:27