5

我正在尝试编写一个通用函数,它将 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只是空。即使不是,它仍然可能无法正常工作。我相信你们会有更聪明的方法(一种真正有效的方法..)来实现这一点。

ps 我正在使用 EF 创建一个作为数据源的列表,因此将数据源转换为 DataTable 在这里可能不相关

4

3 回答 3

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) + "]";
                }

            }
        }
    }

由于绑定数据源提供了来自数据源的对象列表。它很容易遍历绑定源列表。我不知道如何使用对象数据源或 BindingDatasource.Current 执行此操作。我仍在寻找解决方案。

于 2013-01-15T15:45:52.027 回答
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);
   }
于 2012-11-10T23:06:00.183 回答
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

另一方面,如果您有 aDataGridView并且想要添加一行,则可以使用 a BindingSourceas 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());
}
于 2013-01-15T22:36:39.410 回答