将 Datagridview 的 DataSource 转换为 List?
Posted
技术标签:
【中文标题】将 Datagridview 的 DataSource 转换为 List?【英文标题】:Convert Datagridview's DataSource to List? 【发布时间】:2012-10-25 13:48:34 【问题描述】:我正在尝试编写一个通用函数,它将 datagridview 的数据源转换为列表(然后我想向列表中添加一个空对象。数据源可以是任何类型)?
我的一些绝望尝试看起来像这样:
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);
..但the_source
只是空值。即使不是,它仍然可能无法正常工作。我相信你们会有更聪明的方法(一种真正有效的方法..)来实现这一点。
附言我正在使用 EF 创建一个作为数据源的列表,因此将数据源转换为 DataTable 可能与此处无关
【问题讨论】:
不知道为什么这个问题没有得到足够的重视。感谢@Overflow012,我刚刚用正确的类别重新标记了这个问题。希望有人能提供一个很好的解决方案 【参考方案1】:我是通过以下方式完成的(仅当您使用绑定数据源时才有效)
创建自定义datagridview控件并继承datagridview
public partial class MyGridView : DataGridView
声明一个包含列名、摘要值和要显示的格式的类
[Serializable]
public class SummaryDataProperty
public string ColumnName get; set;
public string Format get; set;
internal decimal Value get; set;
在 MyDataGridView 中声明汇总数据属性列表
public List<SummaryDataProperty> SummaryDataPropertyNames get; set;
数据绑定完成后,计算摘要并显示在列标题处。
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) + "]";
由于绑定数据源给出了来自数据源的对象列表。它很容易遍历绑定源列表。我不知道如何使用对象数据源或 BindingDatasource.Current 执行此操作。我仍在寻找解决方案。
【讨论】:
【参考方案2】:这里没有人回答我,所以我最终将类型传递给函数,但如果我能避免这种情况并让函数确定正确的类型,我会更高兴
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);
【讨论】:
【参考方案3】:如果您想要一个通用函数/方法并传递不同对象的列表,您可以这样做(在我的应用程序中提取的示例):
public void SaveAll<T>(IEnumerable<T> objects)
foreach (object obj in objects)
T specificObject = (T)obj;
Session.Save(specificObject);
Session.Flush();
因此,您可以使用任何类对象调用此方法:
List<Product> products = Product.GetAll();
SaveAll<Product>(products);
List<Vendor> vendors = Vendor.GetAll();
SaveAll<Vendor>(vendors);
etc
另一方面,如果您有DataGridView
并且想要添加一行,则可以将BindingSource
用作DataGridView's DataSource
。示例:
...
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());
【讨论】:
以上是关于将 Datagridview 的 DataSource 转换为 List?的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式将新列添加到 DataGridView(填充有 DataTable 的 DataGridview)
如何将 DataGridView 组合框添加到绑定的 DataGridView 数据源(以编程方式)