C# DataGridViewComboBoxColumn 向每一行添加不同的项目。

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/91745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 11:33:03  来源:igfitidea点击:

DataGridViewComboBoxColumn adding different items to each row .

提问by leora

I am building a table using the DataGridView where a user can select items from a dropdown in each cell. To simplify the problem, lets say i have 1 column. I am using the DataGridViewComboBoxColumn in the designer. I am trying to support having each row in that column have a different list of items to choose from.

我正在使用 DataGridView 构建一个表格,用户可以在其中从每个单元格的下拉列表中选择项目。为了简化问题,假设我有 1 列。我在设计器中使用 DataGridViewComboBoxColumn。我试图支持让该列中的每一行都有不同的项目列表可供选择。

Is this possible?

这可能吗?

采纳答案by WaterBoy

Yes. This can be done using the DataGridViewComboBoxCell.

是的。这可以使用 DataGridViewComboBoxCell 来完成。

Here is an example method to add the items to just one cell, rather than the whole column.

这是将项目添加到一个单元格而不是整个列的示例方法。

private void setCellComboBoxItems(DataGridView dataGrid, int rowIndex, int colIndex, object[] itemsToAdd)
{
    DataGridViewComboBoxCell dgvcbc = (DataGridViewComboBoxCell) dataGrid.Rows[rowIndex].Cells[colIndex];
    // You might pass a boolean to determine whether to clear or not.
    dgvcbc.Items.Clear();
    foreach (object itemToAdd in itemsToAdd)
    {
        dgvcbc.Items.Add(itemToAdd);
    }
}

回答by Steve

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == DataGridViewComboBoxColumnNumber)
    {
        setCellComboBoxItems(myDataGridView, e.RowIndex, e.ColumnIndex, someObj);
    }
}

回答by Jay

Just in case anyone finds this thread, this is my solution in VB 2008. The advantage this offers is that it allows you to assign an ID to each value in the combobox.

以防万一有人找到这个线程,这是我在 VB 2008 中的解决方案。它提供的优点是它允许您为组合框中的每个值分配一个 ID。

  Private Sub FillGroups()
    Try
        'Create Connection and SQLCommand here.

        Conn.Open()
        Dim dr As SqlDataReader = cm.ExecuteReader

        dgvGroups.Rows.Clear()

        Dim PreviousGroup As String = ""

        Dim l As New List(Of Groups)

        While dr.Read

            Dim g As New Groups
            g.RegionID = CheckInt(dr("cg_id"))
            g.RegionName = CheckString(dr("cg_name"))
            g.GroupID = CheckInt(dr("vg_id"))
            g.GroupName = CheckString(dr("vg_name"))
            l.Add(g)

        End While
        dr.Close()
        Conn.Close()

        For Each a In (From r In l Select r.RegionName, r.RegionID).Distinct

            Dim RegionID As Integer = a.RegionID 'Doing it this way avoids a warning

            dgvGroups.Rows.Add(New Object() {a.RegionID, a.RegionName})

            Dim c As DataGridViewComboBoxCell = CType(dgvGroups.Rows(dgvGroups.RowCount - 1).Cells(colGroup.Index), DataGridViewComboBoxCell)
            c.DataSource = (From g In l Where g.RegionID = RegionID Select g.GroupID, g.GroupName).ToArray
            c.DisplayMember = "GroupName"
            c.ValueMember = "GroupID"
        Next

    Catch ex As Exception
    End Try
End Sub

Private Class Groups

    Private _RegionID As Integer
    Public Property RegionID() As Integer
        Get
            Return _RegionID
        End Get
        Set(ByVal value As Integer)
            _RegionID = value
        End Set
    End Property

    Private _RegionName As String
    Public Property RegionName() As String
        Get
            Return _RegionName
        End Get
        Set(ByVal value As String)
            _RegionName = value
        End Set
    End Property

    Private _GroupName As String
    Public Property GroupName() As String
        Get
            Return _GroupName
        End Get
        Set(ByVal value As String)
            _GroupName = value
        End Set
    End Property

    Private _GroupID As Integer
    Public Property GroupID() As Integer
        Get            
            Return _GroupID
        End Get
        Set(ByVal value As Integer)
            _GroupID = value
        End Set
    End Property

End Class

回答by Ahmed Soliman Flasha

this is an example with gridView which have 2 comboboxColumns and when a comboBoxColumns1 selected index changed then load comboBoxColumns2 with data from from two different columns from database .

这是一个 gridView 的例子,它有 2 个组合框列,当组合框列1 选择的索引发生变化时,然后用来自数据库的两个不同列的数据加载组合框列2。

 private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
              if (dataGridView1.Rows[e.RowIndex].Cells[0].Value != null && dataGridView1.CurrentCell.ColumnIndex == 0)
            {

                SqlConnection conn = new SqlConnection("data source=.;initial catalog=pharmacy;integrated security=true");
                SqlCommand cmd = new SqlCommand("select [drugTypeParent],[drugTypeChild] from [drugs] where [drugName]='" + dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString() + "'", conn);
                conn.Open();
                SqlDataReader dr = cmd.ExecuteReader();
                while (dr.Read())
                {

                    object[] o = new object[] { dr[0].ToString(),dr[1].ToString() };
                    DataGridViewComboBoxCell dgvcbc = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[1];

                    dgvcbc.Items.Clear();
                    foreach (object itemToAdd in o)
                    {
                        dgvcbc.Items.Add(itemToAdd);
                    }
                }
                dr.Close();
                conn.Close();
               }
            }

回答by jock mcspiffy

    //Populate the Datatable with the Lookup lists
    private DataTable typeDataTable(DataGridView dataGridView, Lookup<string, Element> type_Lookup, Dictionary<Element, string> type_dictionary, string strNewStyle, string strOldStyle, string strID, string strCount)
    {
        int row = 0;

        DataTable dt = new DataTable();

        dt.Columns.Add(strOldStyle, typeof(string));
        dt.Columns.Add(strID, typeof(string));
        dt.Columns.Add(strCount, typeof(int));
        dt.Columns.Add("combobox", typeof(DataGridViewComboBoxCell));



        //Add All Doc Types to ComboBoxes
        DataGridViewComboBoxCell CmBx = new DataGridViewComboBoxCell();
        CmBx.DataSource = new BindingSource(type_dictionary, null);
        CmBx.DisplayMember = "Value";
        CmBx.ValueMember = "Key";


        //Add Style Comboboxes
        DataGridViewComboBoxColumn Data_CmBx_Col = new DataGridViewComboBoxColumn();
        Data_CmBx_Col.HeaderText = strNewStyle;
        dataGridView.Columns.Add(addDataGrdViewComboBox(Data_CmBx_Col, type_dictionary));

        setCellComboBoxItems(dataGridView, 1, 3, CmBx);

        //Add style Rows
        foreach (IGrouping<string, Element> StyleGroup in type_Lookup)
        {
            row++;
            //Iterate through each group in the Igrouping
            //Add Style Rows
            dt.Rows.Add(StyleGroup.Key, row, StyleGroup.Count().ToString());


        }
        return dt;
    }




    private void setCellComboBoxItems(DataGridView dataGrid, int rowIndex, int colIndex, DataGridViewComboBoxCell CmBx)
    {
        DataGridViewComboBoxCell dgvcbc = (DataGridViewComboBoxCell)dataGrid.Rows[rowIndex].Cells[colIndex];
        // You might pass a boolean to determine whether to clear or not.
        dgvcbc.Items.Clear();
        foreach (DataGridViewComboBoxCell itemToAdd in CmBx.Items)
        {
            dgvcbc.Items.Add(itemToAdd);
        }

回答by bh_earth0

setting the comboboxcell right after setting datasource doesnt work for me. it has to be done after binding operations completed. i choosed CellBeginEdit

设置数据源后立即设置组合框对我不起作用。它必须在绑定操作完成后完成。我选择了 CellBeginEdit

example of empty dropdowns:

空下拉列表示例:

dgv1.datasource = datatable1;
dgv1.columns.add ( "cbxcol"  , typeof(string) );

//  different source for each comboboxcell in rows
var dict_rowInd_cbxDs = new Dictionary<int, object>();
dict_rowInd_cbxDs[1] = new list<string>(){"en" , "us"};
dict_rowInd_cbxDs[2] = new list<string>(){ "car", "bike"};

// !!!!!! setting comboboxcell after creating doesnt work here
foreach( row in dgv.Rows.asEnumerable() )
{ 
   var cell = res_tn.dgv.CurrentCell as DataGridViewComboBoxCell;
   cell.DataSource = dict_dgvRowI_cbxDs[res_tn.dgv.CurrentCell.RowIndex];

}

working example:

工作示例:

dgv1.datasource = datatable1;
dgv1.columns.add ( "cbxcol"  , typeof(string) );

//  different source for each comboboxcell in rows
var dict_rowInd_cbxDs = new Dictionary<int, object>();
dict_rowInd_cbxDs[1] = new list<string>(){"en" , "us"};
dict_rowInd_cbxDs[2] = new list<string>(){ "car", "bike"};


// cmboboxcell datasource Assingment Must be done after  BindingComplete (not tested )  or cellbeginEdit  (tested by me)    
res_tn.dgv.CellBeginEdit += (s1, e1) => {
    if (res_tn.dgv.CurrentCell is DataGridViewComboBoxCell) {
        if (dict_dgvRowI_cbxDs.ContainsKey(res_tn.dgv.CurrentCell.RowIndex)) 
        {
            var cll = res_tn.dgv.CurrentCell as DataGridViewComboBoxCell;
            cll.DataSource = dict_dgvRowI_cbxDs[res_tn.dgv.CurrentCell.RowIndex];

           // required if it is  list<mycustomClass>
           // cll.DisplayMember = "ColName";
           // cll.ValueMember = "This";
        }
    }

};