【发布时间】:2016-07-22 09:39:02
【问题描述】:
我想创建一个ObservableList<T>,但作为DynamicObject,所以我可以将元素映射为属性。这就是为什么我必须继承 DynamicObject 而不是 ObservableList<T>。
public class DataFieldList : DynamicObject, ICollection<DataField>, INotifyCollectionChanged
{
private ObservableList<DataField> _list;
public DataFieldList()
{
_list = new ObservableList<DataField>();
}
public Object this[String name]
{
get
{
return _list.FirstOrDefault(x => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase))?.Value;
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this[binder.Name];
return result != null;
}
}
现在我还需要实现接口,所以我可以像ObservableCollection 一样使用类。我想使用我的_list 作为实现这些接口的委托,但这似乎是不可能的......
此功能通过属性的implements 关键字包含在Delphi 中:
property Collection: ICollection read _list implements ICollection;
我知道this 和this 的问题基本上是相同的,但是继承的解决方案对我来说是不可能的,而且我也不能仅仅将接口公开为属性。对于ICollection<T>,即使使用起来有点不方便,这也可以解决,但对于INotifyCollectionChanged 的属性则不行,因为这违背了目的 - 如果接口不是由 WPF 实现的,WPF 不会注意到任何更改我绑定到的对象。
那么有没有其他方法可以获得一个类,它的行为类似于ObservableCollection<T>,但也允许我访问像DynamicObject 这样的动态属性?
用例是一个网格,它获取 DataFieldList 的集合作为源以及列名称的集合。
<Style BasedOn="{StaticResource {x:Type dxg:GridControl}}" TargetType="{x:Type controls:DataGrid}">
<Setter Property="ItemsSource" Value="{TemplateBinding Rows}">
<Setter Property="ColumnsSource" Value="{TemplateBinding Columns}">
<Setter Property="ColumnGeneratorTemplate">
<Setter.Value>
<DataTemplate>
<ContentControl>
<dxg:GridColumn FieldName="{Binding Name}"/>
</ContentControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
这里,Rows 属性包含一个 DataSource,它以 DataFieldList 提供行。
【问题讨论】: