'Databind Object to Winforms DatagridView with ComboBox
Currently I'm trying to databind object properties to a datagridview. The thing is that the datagridview should have a combobox column, where the user has to choose between two values.
The class in question is this one:
public class SingleTableRow
{
/// <summary>
/// Input für datagrid
/// </summary>
public string PropertyName { get; set; }
public string VaultProperty { get; set; }
public string SageProperty { get; set; }
public bool IsSync { get; set; }
public bool AreSame { get; set; }
public bool IsSageLeading { get; set; }
/// <summary>
/// Single Table row constructor
/// </summary>
/// <param name="allValues"></param>
public SingleTableRow(List<string> allValues)
{
PropertyName = allValues[0];
VaultProperty = allValues[1];
SageProperty = allValues[2];
IsSync = false;
IsSageLeading = true;
AreSame = VaultProperty.Equals(SageProperty);
}
}
All values except IsSync should be bound to the Datagridview. The IsSageLeading is a Boolean and indicates, which of the two values should be preselected for the user (Vault or Sage).
Once it is done it should look like this:
I already have a implementation but it only works by creating a DataTable for the String values and then adding a column with combo boxes after that. This is obviously bad design because the last column does not get sorted and does not contain the values of the object.
dtgrid.DataSource = table;
.
.
.
DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
combo.HeaderText = "Führendes System";
combo.Name = "Führendes System";
String[] options = { "Vault", "Sage" };
combo.Items.AddRange(options);
dtgrid.Columns.Add(combo);
How do I apporach this problem best?
Solution 1:[1]
It sounds like you need to map the Boolean
values from IsSageLeading
to one of the two values you want to display (Vault or Sage). As you have already noted, that since the combo box column is NOT part of the data source, then it acts independently from the GRIDS data source.
The code below should allow you to bind the IsSageLeading
property to the combo box column such that a false
value will display as “Vault” and a true
value will be displayed as “Sage.”
There are three properties of the combo box column we need to focus on…The first is the columns DataPropertyName
. This will point to the column in the GRIDS data source… namely the Boolean
IsSageLeading
property.
Next, we need to create a data source for the Combo Box Column. This data source will be a DataTable
with two fields and two rows. The first field which is called ValueMem
is a Boolean
type. The second field which is called DisplayMem
is a string
field. The entire table may look something like below…
ValueMem | DisplayMem |
---|---|
False | Vault |
True | Sage |
This table will be used as a DataSource
for the Combo Box Column. The properties we need to set for the column are the ValueMember
and DisplayMember
which will obviously point to each of the two fields in the combo boxes data source.
The code below should enable you to bind the Boolean
IsSageLeading
property to the combo box column. About the only thing to note is that you need to add the combo box column BEFORE you set the Grids DataSource.
private void Form1_Load(object sender, EventArgs e) {
dataGridView1.Columns.Add(GetComboColumn());
dataGridView1.DataSource = GetGridData();
dataGridView1.Columns["Fuhrendes System"].DisplayIndex = 3;
}
private DataGridViewComboBoxColumn GetComboColumn() {
DataTable dt = new DataTable();
dt.Columns.Add("ValueMem", typeof(bool));
dt.Columns.Add("DisplayMem", typeof(string));
dt.Rows.Add(false, "Vault");
dt.Rows.Add(true, "Sage");
DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
col.HeaderText = "Fuhrendes System";
col.Name = "Fuhrendes System";
col.DataSource = dt;
col.DataPropertyName = "IsSageLeading";
col.ValueMember = "ValueMem";
col.DisplayMember = "DisplayMem";
return col;
}
private DataTable GetGridData() {
DataTable dt = new DataTable();
dt.Columns.Add("PropertyName", typeof(string));
dt.Columns.Add("VaultProperty", typeof(string));
dt.Columns.Add("SageProperty", typeof(string));
dt.Columns.Add("IsSync", typeof(bool));
dt.Columns.Add("AreSame", typeof(bool));
dt.Columns.Add("IsSageLeading", typeof(bool));
Random rand = new Random();
for (int i = 1; i < 10; i++) {
dt.Rows.Add("PropertyName " + i,
"VaultProperty " + i,
"SageProperty " + i,
rand.Next(2) == 1,
rand.Next(2) == 1,
rand.Next(2) == 1
);
}
return dt;
}
This should allow the combo box column to act as a part of the grids data source and not detached as previously described… i.e., sorting and filtering should include the IsSageLeading
column. I hope this makes sense and helps.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |