DataGridViewComboBoxColumn la adición de elementos diferentes para cada fila .
-
01-07-2019 - |
Pregunta
Estoy construyendo una tabla con el DataGridView donde un usuario puede seleccionar elementos de una lista desplegable en cada celda.Para simplificar el problema, digamos que tengo 1 columna.Yo estoy usando la DataGridViewComboBoxColumn en el diseñador.Estoy tratando de admitir la necesidad de cada fila de esa columna tiene una lista diferente de elementos para elegir.
Es esto posible?
Solución
Sí.Esto puede ser hecho usando el DataGridViewComboBoxCell.
Aquí es un ejemplo de método para agregar los elementos a sólo una célula, en lugar de toda la columna.
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);
}
}
Otros consejos
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == DataGridViewComboBoxColumnNumber)
{
setCellComboBoxItems(myDataGridView, e.RowIndex, e.ColumnIndex, someObj);
}
}
Sólo en caso de que alguien encuentre este hilo, esta es mi solución en VB 2008.La ventaja que ofrece es que permite asignar un IDENTIFICADOR a cada valor de la lista desplegable.
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
este es un ejemplo con gridView, que tienen 2 comboboxColumns y cuando un comboBoxColumns1 índice seleccionado cambiado, a continuación, cargar comboBoxColumns2 con datos de dos columnas diferentes de la base de datos .
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();
}
}
ajuste de la comboboxcell a la derecha después de la configuración de origen de datos no funciona para mí.esto tiene que ser hecho después de que la unión operaciones completadas.yo he elegido CellBeginEdit
ejemplo de vacío listas desplegables:
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];
}
ejemplo de trabajo:
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);
}