Convert Datagridview DataSource to List?

I am trying to write a generic function that converts a datasource datagridview to a list (then I want to add an empty list to the list. Can the data source be of any type)?

Some of my desperate attempts looked like this:

Type datagrid_type = dgv.DataSource.GetType(); List<object> the_source = dgv.DataSource as List<object>; Convert.ChangeType(the_source, datagrid_type); Object c = Activator.CreateInstance(datagrid_type); Convert.ChangeType(c, datagrid_type); the_source.Add(c); 

.. but the_source is null. even if it weren’t, it probably didn’t work. I am sure that you guys will have a smarter way (the one that actually works ...) to achieve this.

ps I use EF to create a list that is a data source, so casting a data source in a DataTable probably doesn't matter here.

+4
source share
3 answers

I did it as follows (only works when you use a binding data source)

Create a custom datagridview control and inherit datagridview

 public partial class MyGridView : DataGridView 

Declare the class that contains the column name, the final value, and the format that will be displayed

  [Serializable] public class SummaryDataProperty { public string ColumnName { get; set; } public string Format { get; set; } internal decimal Value { get; set; } } 

Declare a list of summary properties in MyDataGridView

  public List<SummaryDataProperty> SummaryDataPropertyNames { get; set; } 

After the data binding is complete, calculate the summary and display it in the column heading.

  protected override void OnDataBindingComplete(DataGridViewBindingCompleteEventArgs e) { base.OnDataBindingComplete(e); if (SummaryDataPropertyNames.Count > 0) { if (DataSource is BindingSource) { var ds = (DataSource as BindingSource); foreach (var prop in SummaryDataPropertyNames) { prop.Value = 0; var col = this.Columns[prop.ColumnName]; foreach (var l in ds.List) { decimal val; if (decimal.TryParse(Convert.ToString(l.GetType().GetProperty(col.DataPropertyName).GetValue(l, null)), out val)) prop.Value += val; } col.HeaderText = col.HeaderText.Split('[')[0].TrimEnd(' ') + " [" + prop.Value.ToString(prop.Format) + "]"; } } } } 

Since the binding data source gives a list of objects from the data source. It is easy to iterate through a list of binding sources. I do not know how to do this with an object data source or BindingDatasource.Current. I'm still looking for a solution.

+3
source

No one answered me, so I passed the type of the function, although I would be happier if I could avoid it, and let the function determine the correct type

 public static void Add_Empty_Row_At_To_Grid<T>(DataGridView dgv) { List<T> the_source = dgv.DataSource as List<T>; T c = (T)Activator.CreateInstance(typeof(T)); the_source.Add(c); } 
+2
source

If you want to use a common function / method and pass a list of different objects, you can do this (example extracted in my application):

 public void SaveAll<T>(IEnumerable<T> objects) { foreach (object obj in objects) { T specificObject = (T)obj; Session.Save(specificObject); } Session.Flush(); } 

So you can call this method with any class object:

 List<Product> products = Product.GetAll(); SaveAll<Product>(products); List<Vendor> vendors = Vendor.GetAll(); SaveAll<Vendor>(vendors); etc 

On the other hand, if you have a DataGridView and you want to add a row, you can use BindingSource as a DataGridView DataSource . Example:

 ... private BindingSource Source; ... private void LoadProducts(List<Product> products) { Source.DataSource = products; ProductsDataGrid.DataSource = Source; } private void addProductBtn_Click(object sender, EventArgs e) { Source.Add(new Product()); } 
+1
source

Source: https://habr.com/ru/post/1444164/


All Articles