我正在尝试编写一个将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
只是空的。即使它不是它仍然可能不会工作。我相信你们会有一个更聪明的方式(一个真正有用的方法......)来实现这个目标。
P.S。我正在使用EF创建一个数据源列表,因此将数据源转换为DataTable可能与此无关
答案 0 :(得分:3)
我是按照以下方式完成的(仅在使用绑定数据源时才有效)
创建自定义datagridview控件并继承datagridview
public partial class MyGridView : DataGridView
声明一个包含columnname,summaryvalue和要显示的格式的类
[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) + "]";
}
}
}
}
由于绑定数据源提供了来自数据源的对象列表。它很容易遍历绑定源列表。我不知道如何使用object datasource或BindingDatasource.Current来做到这一点。我仍在寻找解决方案。
答案 1 :(得分: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);
}
答案 2 :(得分:1)
如果你想要一个通用的函数/方法并传递一个不同的对象列表,你可以这样做(在我的应用程序中提取的一个例子):
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());
}