簡體   English   中英

C#通過委托實現接口

[英]C# Implement interface through delegate

我想創建一個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;

我知道, 這個這個問題基本上是相同的,但繼承的解決方案是不可能的,我的,也是我真的不能只是公開的接口作為屬性。 即使對於ICollection<T> ,即使使用起來有點不便,但對於INotifyCollectionChanged的屬性,即使這樣做使用起來也不INotifyCollectionChanged ,因為這無法達到目的-如果接口不是由對象實現的,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屬性包含一個數據源,該數據源將行作為DataFieldList提供。

如果我正確理解您的意思,您應該會得到這樣的信息

public class DataField
{
    public string Name { get; set; }

    public object Value { get; set; }
}

public class PropertiesCollection
{
    public PropertiesCollection(IEnumerable<DataField> collection)
    {
        _collection = collection;
    }

    private IEnumerable<DataField> _collection;

    public object this[string name]
    {
        get
        {
            return _collection.FirstOrDefault(x => x.Name.Equals(name, StringComparison.OrdinalIgnoreCase))?.Value;
        }
    }
}

public class CustomList : ObservableCollection<DataField>
{
    private PropertiesCollection _collection;

    public CustomList()
    {
        _collection = new PropertiesCollection(this);
    }

    public PropertiesCollection Properties
    {
        get
        {
            return _collection;
        }
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(nameof(Properties)));
        base.OnCollectionChanged(e);
    }
}

綁定看起來像這樣:

    <TextBlock Text="{Binding Properties[SomeProperty],Mode=OneWay}">            
    </TextBlock>

即我只使用合成而不是繼承。 不幸的是,我們只需要滿足於組合(並且您很清楚C#不支持多重繼承。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM