C# 如何将数据绑定到与派生列表的类中的列表项不关联的属性<;T>;

C# 如何将数据绑定到与派生列表的类中的列表项不关联的属性<;T>;,c#,generics,data-binding,C#,Generics,Data Binding,以前,我有一个类包装了一个内部System.Collections.Generic.List(其中Item是我创建的类)。包装器类提供了几个集合级属性,这些属性提供了列表中项目的总计、平均值和其他计算。我正在围绕这个包装的列表创建一个BindingSource,围绕我的类创建另一个BindingSource,并且能够通过第一个BindingSource和使用第二个BindingSource>的包装类的集合级属性来获取包装列表中的项 一个简化的示例如下所示: public class OldCla

以前,我有一个类包装了一个内部
System.Collections.Generic.List
(其中Item是我创建的类)。包装器类提供了几个集合级属性,这些属性提供了列表中项目的总计、平均值和其他计算。我正在围绕这个包装的
列表创建一个
BindingSource
,围绕我的类创建另一个
BindingSource
,并且能够通过第一个
BindingSource
和使用第二个
BindingSource>的包装类的集合级属性来获取包装列表中的项

一个简化的示例如下所示:

public class OldClass()
{
  private List<Item> _Items;

  public OldClass()
  {
    _Items = new List<Item>();
  }

  public List<Item> Items { get { return _Items; } }

  // collection-level properties
  public float AverageValue { get { return Average() } }
  public float TotalValue { get { return Total() } }
  // ... other properties like this

}
最近,我尝试将此类更改为从
System.Collections.Generic.List
派生,而不是保留一个包装的
List
成员。我希望摆脱额外的包装层,只使用一个而不是两个
BindingSource
。但是,现在我发现,在执行数据绑定时,无法获取适用于列表中所有项的属性(例如
AverageValue
)。只有列表项的属性可用


我是否被迫重新使用
项的包装
列表
?或者是否有一种方法可以同时获取存储在新类中的
项的属性以及应用于集合本身的属性?

这里的问题是,您希望将一个类用于两个完全不同的目的(就绑定而言)

示例:“AverageValue”属性在每个项上都没有意义,因为它是一个跨越所有项的全局属性

不管怎样,我猜您的_itemsBindingSource是用于组合框之类的,而您的_summaryBindingSource是用于PropertyGrid之类的

你能做的,在你的情况下可能有用的(我不能确定,因为我不知道你实际上在做什么)是:

1) 让你的“旧类”实现IEnumerable。。。在这种情况下,只需从列表中返回枚举。这将使您能够绑定到“oldClass”而不是“oldClass.Items”


2) 将“公共列表项”设置为字段,而不是属性。。。或者添加“Browsable(false)”属性,这样它就不会绑定到PropertyGrid(这是一个猜测,因为不清楚您使用这些绑定的目的是什么)。

系统将实现
IList
(或
IListSource
)的任何内容视为一个容器,而不是一个项。因此,您不能绑定到任何实现
IList
的对象的属性。因此,如果您希望能够绑定到容器的属性,封装(即您已经拥有的)是最好的方法

但是,您应该注意,许多绑定在源代码中支持点表示法,即绑定到“Items.SomeProperty”,或者设置辅助属性(通常是
DataMember
)以指定子列表


这允许您拥有一个
BindingSource
,并将不同的控件绑定到层次结构中的不同级别-即,您可以将
TextBox
绑定到
AverageValue
,以及具有
DataMember=“Items”的
DataGridView
(使用相同的
DataSource

您是否考虑过创建一个扩展类(假设您使用的是C#3),而不是围绕列表创建一个包装类

公共静态类MyExtensions
{
公共静态浮点GetAverage(此列表)
{
//实施
}
公共静态浮点GetTotal(此列表)
{
//实施
}
}
当然,您的属性变成了方法调用(),但您将完全消除包装器

_itemsBindingSource = new BindingSource(oldClass.Items);
_summaryBindingSource = new BindingSource(oldClass);
public static class MyExtensions
{
    public static float GetAverage(this List<Item>)
    {
        // implementation
    }

    public static float GetTotal(this List<Item>)
    {
        // implementation
    }
}