I have an existing Data Grid View whose DataSource is a Data Table that I populate from a list of a custom object.
private myDataTable = new DataTable();
List<SomeObjectModel> dataSource = (from e in queryResults
select
new SomeObjectModel
{
Id = e.Id,
Priority = e.Name,
Channel = e.Channel
}).ToList();
myDataTable = ToDataTable(dataSource); //See method below
dataGridView.DataSource = myDataTable;
From a previous question on StackOverflow, I found the ToDataTable method I'm using there that works for turning my list of objects into a DataTable using Reflection:
public static DataTable ToDataTable<T>(List<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in Props)
{
dataTable.Columns.Add(prop.Name);
}
foreach (T item in items)
{
var values = new object[Props.Length];
for (int i = 0; i < Props.Length; i++)
{
values[i] = Props[i].GetValue(item, null);
}
dataTable.Rows.Add(values);
}
dataTable.AcceptChanges();
return dataTable;
}
This works for all of my DataGridViewTextBox columns. Now, I would like to add a new DataGridViewComboBoxColumn called "Person" to the data grid that has a ValueMember = "PersonId" and a DisplayMember = "PersonName" populated from a list of a Person object.
I'm getting stuck here understanding how to add this type of column to my data grid from a Data Table.
My Person object simply has the properties PersonId and PersonName, again, which I would like to use as the ValueMember and DisplayMember of the combo box.
I'm stuck, but my thinking is: 1.) Update SomeObjectModel to contain Person, 2.) Update ToDataTable method to contain an if clause to catch when the item name is "Person", but I'm not sure what to do for the rows. Also, it feels hacky to simply look for the property name, as I would like to keep ToDataTable clean.
public static DataTable ToDataTable<T>(List<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in Props)
{
if (prop.Name = "Person") { // Create DataGridViewComboBoxColumn }
else
{
dataTable.Columns.Add(prop.Name);
}
}
foreach (T item in items)
{
var values = new object[Props.Length];
for (int i = 0; i < Props.Length; i++)
{
values[i] = Props[i].GetValue(item, null);
}
dataTable.Rows.Add(values);
}
dataTable.AcceptChanges();
return dataTable;
}
DataGridViewto aDataTablewhich you created using aList<SomeObjectModel>? - Reza AghaeiToDataTablemethod needs a fix when adding columns, you should add columns this way:dataTable.Columns.Add(prop.Name, prop.PropertyType);. If you don't specify the type of column it would be of string type. - Reza AghaeiTextBoxis completely possible usingLinq. For example, take a look at this post or this one. - Reza Aghaei