يقوم DataGridViewComboBoxColumn بإضافة عناصر مختلفة إلى كل صف.

StackOverflow https://stackoverflow.com/questions/91745

  •  01-07-2019
  •  | 
  •  

سؤال

أقوم بإنشاء جدول باستخدام DataGridView حيث يمكن للمستخدم تحديد العناصر من القائمة المنسدلة في كل خلية.لتبسيط المشكلة، لنفترض أن لدي عمودًا واحدًا.أنا أستخدم DataGridViewComboBoxColumn في المصمم.أحاول دعم أن يحتوي كل صف في هذا العمود على قائمة مختلفة من العناصر للاختيار من بينها.

هل هذا ممكن؟

هل كانت مفيدة؟

المحلول

نعم.ويمكن القيام بذلك باستخدام DataGridViewComboBoxCell.

فيما يلي مثال لطريقة إضافة العناصر إلى خلية واحدة فقط، بدلاً من العمود بأكمله.

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);
    }
}

نصائح أخرى

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

فقط في حالة عثور أي شخص على هذا الموضوع، فهذا هو الحل الخاص بي في VB 2008.الميزة التي يقدمها هذا هو أنه يسمح لك بتعيين معرف لكل قيمة في مربع التحرير والسرد.

  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

هذا مثال على GridView الذي يحتوي على 2 comboboxColumns وعندما يتغير الفهرس المحدد comboBoxColumns1، قم بتحميل comboBoxColumns2 ببيانات من عمودين مختلفين من قاعدة البيانات.

 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();
               }
            }

ضبط comboboxcell مباشرة بعد تعيين مصدر البيانات لا يعمل بالنسبة لي.يجب أن يتم ذلك بعد اكتمال عمليات الربط.لقد اخترت CellBeginEdit

مثال على القوائم المنسدلة الفارغة:

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];

}

مثال العمل:

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";
        }
    }

};
    //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);
        }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top