• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:VB.NET2003のDataGridでコンボボックス)

VB.NET2003のDataGridでコンボボックス

このQ&Aのポイント
  • VB.NET2003のDataGridでコンボボックスを作成する方法と選択した値の取得方法について調査中です。
  • DataGridに異なる値のコンボボックスを行ごとに作成することも可能か確認中です。
  • VB.NET2003のDataGridでコンボボックスを作成する方法について知りたいです。また、選択した値を取得する方法や行ごとに異なる値のコンボボックスを作成する方法についても教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

>行ごとに違うリストのコンボボックスを表示させたいのです それもDOBONさんのクラスを改造したら可能です。 あまり難しく考えず、コードをよく見てみましょうね^^; この手のオブジェクト継承は、難しく捉われがちですが、 DOBONさんのサンプルは非常によくまとまっているし、 デバッグしたら、それほぞ難しいことはしておりません。 コメントも付いてるし。。。。 改造は[DataGridComboBoxColumn]クラス部だけでよいです。 [DataGridComboBox]はそのままです。 -------------------------------------------------------------------------------- Public Class DataGridComboBoxColumn   Inherits DataGridTextBoxColumn   Private _comboBox() As DataGridComboBox   Private _sorce As CurrencyManager   Private _rowNumber As Integer   Private _editing As Boolean   '/ <summary>   '/ DataGridComboBoxColumnのコンストラクタ   '/ </summary>   '/ <param name="dataSource">ComboBoxのDataSource</param>   '/ <param name="displayMember">ComboBoxのDisplayMember</param>   '/ <param name="valueMember">ComboBoxのValueMember</param>   Public Sub New( _       ByVal dataSource() As DataView, _       ByVal displayMember As String, _       ByVal valueMember As String)     '初期設定     _sorce = Nothing     _editing = False     ReDim _comboBox(dataSource.Length - 1)     Dim l_combo As DataGridComboBox     Dim i As Integer     For i = 0 To _comboBox.Length - 1       Call myNew(_comboBox(i), dataSource(i), displayMember, valueMember)     Next   End Sub   'プロパティ   '/ <summary>   '/ 管理されている ComboBox コントロールを取得します。   '/ </summary>   Public ReadOnly Property ComboBox() As DataGridComboBox     Get       Return GetActiveCombobox(_rowNumber)     End Get   End Property   'ComboBoxからフォーカスが離れた   Private Sub _comboBox_Leave(ByVal sender As Object, _       ByVal e As EventArgs)     If _editing Then       'ComboBoxが編集中だったとき       _editing = False       '行の値を更新する       SetColumnValueAtRow(_sorce, _rowNumber, _         GetActiveCombobox(_rowNumber).Text)       Invalidate()     End If     'ComboBoxを隠す     GetActiveCombobox(_rowNumber).Visible = False     'DataGridのスクロールイベントを捕捉する     AddHandler DataGridTableStyle.DataGrid.Scroll, _       AddressOf DataGrid_Scroll   End Sub   'DataGridがスクロール   Private Sub DataGrid_Scroll(ByVal sender As Object, _       ByVal e As EventArgs)     'ComboBoxを消す     If GetActiveCombobox(_rowNumber).Visible Then       GetActiveCombobox(_rowNumber).Visible = False     End If   End Sub   'ComboBoxで選択した項目が変更されて、その変更がコミットされた   Private Sub _comboBox_SelectionChangeCommitted( _       ByVal sender As Object, ByVal e As EventArgs)     _editing = True     'DataGridに列が編集開始されたことを知らせる     MyBase.ColumnStartedEditing(CType(sender, Control))   End Sub   '行の最小の高さ   Protected Overrides Function GetMinimumHeight() As Integer     Return GetActiveCombobox(_rowNumber).PreferredHeight   End Function   'ComboBoxをDataGridのControl.ControlCollectionに追加する   Protected Overrides Sub SetDataGridInColumn( _       ByVal value As DataGrid)     MyBase.SetDataGridInColumn(value)     Dim l_combo As DataGridComboBox     For Each l_combo In _comboBox       l_combo.Parent = CType(value, Control)     Next   End Sub   '列が管理しているコントロールへのフォーカスを   '放棄する必要があることを列に通知   Protected Overrides Sub ConcedeFocus()     MyBase.ConcedeFocus()     GetActiveCombobox(_rowNumber).Visible = False   End Sub   ''編集するためにセルを準備する   Protected Overloads Overrides Sub Edit( _       ByVal source As CurrencyManager, _       ByVal rowNum As Integer, _       ByVal bounds As Rectangle, _       ByVal [readOnly] As Boolean, _       ByVal instantText As String, _       ByVal cellIsVisible As Boolean)     '基本クラスのEditを呼び出す     MyBase.Edit(source, rowNum, bounds, [readOnly], _       instantText, cellIsVisible)     'TextBoxを消す     Me.TextBox.Visible = False     '値の保存     _rowNumber = rowNum     _sorce = source     '表示させるComboBoxの設定をする     GetActiveCombobox(rowNum).Bounds = bounds     GetActiveCombobox(rowNum).RightToLeft = _       Me.DataGridTableStyle.DataGrid.RightToLeft     '非表示、読み取り専用のときは、ComboBoxを表示しない     If cellIsVisible AndAlso Not [readOnly] Then       'ComboBoxを表示       GetActiveCombobox(rowNum).Visible = True       GetActiveCombobox(rowNum).BringToFront()       GetActiveCombobox(rowNum).Focus()     End If     '選択項目の変更     'ComboBoxを表示する前に行うと、     '新しい行で値を変更した時不都合が起きる     GetActiveCombobox(rowNum).SelectedIndex = _       GetActiveCombobox(rowNum).FindStringExact(Me.TextBox.Text)     'DataGridのスクロールイベントを捕捉する     AddHandler DataGridTableStyle.DataGrid.Scroll, _       AddressOf DataGrid_Scroll   End Sub   '編集プロシージャを完了する   Protected Overrides Function Commit( _       ByVal dataSource As CurrencyManager, _       ByVal rowNum As Integer) As Boolean     If _editing Then       '編集中のときは、rowNum行の値を設定する       _editing = False       SetColumnValueAtRow(dataSource, rowNum, _         GetActiveCombobox(rowNum).Text)     End If     Return True   End Function   '指定した行の値を設定   Protected Overrides Sub SetColumnValueAtRow( _       ByVal source As CurrencyManager, _       ByVal rowNum As Integer, ByVal value As Object)     'ValueMemberの値を設定する     MyBase.SetColumnValueAtRow(source, rowNum, _       GetActiveCombobox(rowNum).FindValueMember(value))   End Sub   '指定した行の値を取得   Protected Overrides Function GetColumnValueAtRow( _       ByVal source As CurrencyManager, _       ByVal rowNum As Integer) As Object     Dim val As Object = _       MyBase.GetColumnValueAtRow(source, rowNum)     'DisplayMemberの値を返す     Return GetActiveCombobox(rowNum).FindDisplayMember(val)   End Function   'NEW用の関数   Private Sub myNew( _         ByRef _combo As DataGridComboBox, _         ByVal dataSource As DataView, _         ByVal displayMember As String, _         ByVal valueMember As String)     'DataGridComboBoxの作成     _combo = New DataGridComboBox()     'ComboBoxの設定     _combo.DropDownStyle = ComboBoxStyle.DropDownList     _combo.Visible = False     'データソースの設定     _combo.DataSource = dataSource     _combo.DisplayMember = displayMember     _combo.ValueMember = valueMember     'イベントハンドラ     AddHandler _combo.Leave, AddressOf _comboBox_Leave     AddHandler _combo.SelectionChangeCommitted, _       AddressOf _comboBox_SelectionChangeCommitted   End Sub   '配列要素からN(ROW)番を考慮し、データグリッドコンボボックスを返却する   Private Function GetActiveCombobox(ByVal rowNum As Integer) As DataGridComboBox     Dim l_index As Integer = (rowNum Mod _comboBox.Length)     Return _comboBox(l_index)   End Function End Class -------------------------------------------------------------------------------- 画面側は、DATAVIEWを配列で渡します。 下のサンプルは配列要素2ですが、いくつでも良いです。 -------------------------------------------------------------------------------- Dim dt As New DataTable("DataTable1") dt.Columns.Add("Column1", GetType(Integer)) dt.Rows.Add(New Object() {5}) dt.Rows.Add(New Object() {9}) dt.Rows.Add(New Object() {3}) dt.Rows.Add(New Object() {1}) dt.Rows.Add(New Object() {4}) dt.Rows.Add(New Object() {3}) dt.Rows.Add(New Object() {7}) dt.Rows.Add(New Object() {6}) dt.Rows.Add(New Object() {10}) 'DataGridで表示するデータソースに設定 DataGrid1.DataSource = dt 'DataGridTableStyleの作成 Dim ts As New DataGridTableStyle() ts.MappingName = "DataTable1" 'DataGridComboBoxColumnで使用するDataTableの作成 '"DisplayMember"列はComboBoxに表示される値 '"ValueMember"列は実際の値 Dim comboSorce1 As New DataTable("ComboBox") With comboSorce1   .Columns.Add("DisplayMember", GetType(String))   .Columns.Add("ValueMember", GetType(Integer))   .Rows.Add(New Object() {"一", 1})   .Rows.Add(New Object() {"二", 2})   .Rows.Add(New Object() {"三", 3})   .Rows.Add(New Object() {"四", 4})   .Rows.Add(New Object() {"五", 5})   .Rows.Add(New Object() {"六", 6})   .Rows.Add(New Object() {"七", 7})   .Rows.Add(New Object() {"八", 8})   .Rows.Add(New Object() {"九", 9})   .Rows.Add(New Object() {"十", 10}) End With Dim comboSorce2 As DataTable = comboSorce1.Clone With comboSorce2   .Rows.Add(New Object() {"(1)", 1})   .Rows.Add(New Object() {"(2)", 2})   .Rows.Add(New Object() {"(3)", 3})   .Rows.Add(New Object() {"(4)", 4})   .Rows.Add(New Object() {"(5)", 5})   .Rows.Add(New Object() {"(6)", 6})   .Rows.Add(New Object() {"(7)", 7})   .Rows.Add(New Object() {"(8)", 8})   .Rows.Add(New Object() {"(9)", 9})   .Rows.Add(New Object() {"(10)", 10}) End With Dim l_dvw() As DataView = New DataView() {comboSorce1.DefaultView, comboSorce2.DefaultView} 'DataGridComboBoxColumnの作成 Dim cbc As New Dobon.Samples.Forms.DataGridComboBoxColumn( _   l_dvw, "DisplayMember", "ValueMember") cbc.MappingName = "Column1" cbc.HeaderText = "数字" '列スタイルの追加 ts.GridColumnStyles.Add(cbc) 'テーブルスタイルの追加 DataGrid1.TableStyles.Add(ts) -------------------------------------------------------------------------------- コンボボックスの切り替えは、 DataGridComboBoxColumn.GetActiveCombobox にて行っております。 法則を変更したければ、そちらを改造してください。

noname#23059
質問者

お礼

ありがとうございました! できました!! 本当にお世話になりました。 >あまり難しく考えず、コードをよく見てみましょうね^^; そうですね^^; 反省・・・。 じっくりコードを見直して勉強します!

その他の回答 (1)

回答No.1

>CStr(DataGrid1(row,col)) これは画面を見ているだけなので、グリッドのデータソースへの反映値を読んだらいいです。 ついでなので、値からDOBONさんのクラスを利用した変換方法も書いておきます。 Dim l_tbl As DataTable = DirectCast(DataGrid1.DataSource, DataTable) Dim i, j As Integer Dim l_str画面 As String Dim l_str値_GridTable As String Dim l_str値_画面より算出 As String Dim ts As DataGridTableStyle Dim cbc As Dobon.Samples.Forms.DataGridComboBoxColumn Dim cb As Dobon.Samples.Forms.DataGridComboBox Dim l_strテーブル名 As String = l_tbl.TableName Dim l_strカラム名 As String If Me.DataGrid1.TableStyles.Contains(l_strテーブル名) Then   ts = Me.DataGrid1.TableStyles(l_strテーブル名) Else   MsgBox("スタイル設定なし")   Return End If For i = 0 To l_tbl.Columns.Count - 1   l_strカラム名 = l_tbl.Columns(i).ColumnName   If ts.GridColumnStyles.Contains(l_strカラム名) Then     cbc = ts.GridColumnStyles(l_strカラム名)     cb = cbc.ComboBox   Else     l_str値_画面より算出 = "《設定されていません》"     cb = Nothing   End If   For j = 0 To l_tbl.Rows.Count - 1     '画面上の値     l_str画面 = DataGrid1.Item(j, i)     'Gridのテーブルの反映値     l_str値_GridTable = l_tbl.Rows(j).Item(i).ToString     If Not (cb Is Nothing) Then       '値からクラスを利用して、求めた値       l_str値_画面より算出 = cb.FindValueMember(l_str画面)     End If     Console.WriteLine( _       "ROW={0}:COL{1}:表示は{2}:Gridの値は{3}:表示から変換した値は{4}" _       , j, i _       , l_str画面 _       , l_str値_GridTable _       , l_str値_画面より算出 _     )   Next Next それと、 >毎に違う値(リストデータ)のコンボボックスを作成 できます。 グリッドに2列目を作成。さらにその2列目用のスタイルを作成しマッピングしてあげたらよいです。

noname#23059
質問者

お礼

わざわざコードまでご丁寧にありがとうございます! おかげさまで値の取得ができました! >>毎に違う値(リストデータ)のコンボボックスを作成 >できます。 >グリッドに2列目を作成。さらにその2列目用のスタイルを>作成しマッピングしてあげたらよいです。 えっと、すみません。 行ごとに違うリストのコンボボックスを表示させたいのです。 別の列に違うコンボボックスを表示するのはできてるのですが、1つの列内の違う行に表示させることはできますでしょうか?

関連するQ&A

専門家に質問してみよう