none
DataGridViewのComboBoxについて RRS feed

  • 質問

  •  DataGridViewのComboBoxについてですが リストにある値を選択することは出来るのですが 普通のComboBoxのように直接値を入力する事ができません 普通のComboBoxのようなDropDounStyleのような設定はできないのでしょうか? 

     簡単なことかも知れませんが よろしくお願い致します。

     

    2006年6月12日 11:15

すべての返信

  • Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) _
                                                 Handles DataGridView1.EditingControlShowing
        Dim cmbItem As ComboBox = CType(e.Control, ComboBox)
        cmbItem.DropDownStyle = ComboBoxStyle.DropDown
    End Sub
    こういう事かな・・・
    あくまで、DropDownスタイルにするだけなので、実際には、CellValidatingイベントなどでアイテム追加などの処理も実装しないといけないですね。
    2006年6月12日 12:08
  •  うなまなさん ありがとうございます

    頂いたコードを下記のように書いて試してみたのですが ComboBoxをクリックすると「型’System.Windows.Forms.DataGridViewTextBoxEditingControl ’ のオブジェクトを型 ’System.Windows.Forms.ComboBox ’ にキャストできません。」と出てしまいました。 どこか おかしいところありますか?

     

        Private Sub View1_EditingControlShowing(ByVal sender As Object,  _

               ByVal e As  _

               System.Windows.Forms. _

               DataGridViewEditingControlShowingEventArgs)  _

               Handles View1.EditingControlShowing


            Dim cmbItem As ComboBox = CType(e.Control, ComboBox)
            cmbItem.DropDownStyle = ComboBoxStyle.DropDown
        End Sub

     

    2006年6月12日 12:53
  • 基本的には出来ません。
    DataGridViewComboBoxColumn クラスのHELPを見てください。
    解説の後ろのほうに以下のように書いてあります。

     DataGridViewComboBoxColumn クラスのHELP さんからの引用

    DataGridViewComboBoxColumn は、DataGridView.DataSource プロパティによって決定されるすべてのセル値と、DataSource プロパティまたは Items プロパティによって決定される一連の選択肢との間にマップが存在する場合のみ、正常に機能します。このマップが存在しない場合は、列が表示されたときに "書式設定と表示でエラーが発生しました" というメッセージが表示されます。

    普通のComboBoxのようなDropDounStyleのような場合は直接値を入力したらSelectIndexが-1になりますが、この-1がDataGridView.DataSource プロパティによって決定されるすべてのセル値のデータバインドに失敗する矛盾があるわけです。

    つまり、直接値を入力した場合、選択肢の候補となる側とのデータのバインドをどう処理するか問われているわけです。
    DataGridViewComboBoxColumn クラスは直接値を選択肢の候補に追加することをしないでエラー扱いをするのです。

    この場合、直接値を入力したいなら選択肢の候補となる側とのデータのバインドを追加してバインドを処理するという方針と、
    バインドに失敗するので選択肢の候補以外だがエラーとせず表示させてバインドを行わないで保存時に適切な方法で処理する方針に分かれるでしょう。
    いずれにしろ DataGridViewComboBoxCell / DataGridViewComboBoxColumn / DataGridViewComboBoxEditingControl を継承することになるでしょう。

    2006年6月12日 15:46
  • このように解決している例もありますね。

    Problem with combobox and databound datagridview
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=13855&SiteID=1

    2006年6月13日 2:54
    モデレータ
  •  皆さん、ありがとうございます。

     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     
            View2.EditMode = DataGridViewEditMode.EditOnEnter
      End Sub

        Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, _
            ByVal e As DataGridViewEditingControlShowingEventArgs) _
            Handles View2.EditingControlShowing

            Dim comboBox1 As ComboBox = CType(e.Control, ComboBox)
            comboBox1.DropDownStyle = ComboBoxStyle.DropDown

        End Sub

     この二つのプロシージャで なんとか 入力できるようになったのですが

    フォーカスが外れると 値が消えてしまいます 

    その時入力した値を 変数に格納して itemに追加でもすればよいのかと思ったのですが CurrentCell.Valueなどでは取り出せません

    どうして 取り出せば良いのでしょうか 又、他に良い方法は有りますか?

     

    2006年6月13日 11:24
  •     Private Sub View2_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles View2.CellValidating
           

            Dim tx As String = e.FormattedValue.ToString()
            If Not tx Is Nothing And tx <> "" Then
                Dim o As Object
                Dim ari As Boolean = False
                For Each o In Column1.Items

                    If o = tx Then
                        ari = True
                    End If
                Next

                If ari = False Then
                    Column1.Items.Add(tx)
                End If
                View2.CurrentCell.Value = tx

            End If

        End Sub

     皆さん、ありがとうございます

    このプロシージャを追加する事で 値が残るようになりました

    でも なぜか itemに既に有る値を入力しても itemに追加されてしまいます

              If ari = False Then

    の前で ari=ture になっているのに追加されるのはなぜでしょう?

     

    2006年6月13日 12:39
  •     Sub itm整理()
            Dim it(0) As Object
            Dim itm As String
            Dim c As Integer = 0
            For Each itm In Column1.Items
                Dim ari As Boolean = False
                For Each i As Object In it
                    If i = itm Then
                        ari = True
                        Exit For
                    End If
                Next
                If ari = False Then
                    ReDim Preserve it(c)
                    it(c) = itm
                    c += 1
                End If
            Next
            Column1.Items.Clear()
            Column1.Items.AddRange(it)
        End Sub

    こんなプロシージャを作って入れてみたら 一応うまくいきました

    こんなんで 良かったんでしょうか?

    なにか、おかしい所があったら 御教授ください。

    2006年6月13日 14:00
  •  申し訳ございません

    先ほどの itm整理のプロシージャは必要ありませんでした

    CurrentCellChangeのところに item.addを入れたままにしておりました

    皆さん、ありがとうございました。

    2006年6月13日 14:29
  • 今回の場合、「直接値を入力したいなら選択肢の候補となる側とのデータのバインドを追加してバインドを処理するという方針」で対応され、
    DataGridView.DataSource プロパティのデータバインドではなくItems プロパティを使っていたので簡単に済んでよかったですね。

    事例として記憶しておきます。ありがとうございました。

    2006年6月14日 5:46
  •  こちらこそ、有難う御座いました

     私は決してプログラマーではなく元々エクセルのVBAから始めて今はVB2005を使ってますが 単に自分の仕事にプログラムを使っているだけなんです 殆ど本屋さんに売ってる本だけで覚えてきた我流ですので 結果は正しく出ていても 全く無駄なコーディングをしてるのが殆どではないかと思います。

     基礎編の本は殆ど買い漁って読んだのですが 一歩上の本を見ると全く書いてある事の意味が分からないし 又、何をする時に必要なのも分からないのが現状です。

     また、とんでもないような 或いは 簡単な質問をするかも知れませんが これからもどうぞ宜しくお願い致します。

    2006年6月14日 8:46