2016-07-22 3 views
0

Я хочу создать ObservableList<T>, но как DynamicObject, поэтому я могу отображать элементы как свойства. Вот почему я должен унаследовать от DynamicObject вместо ObservableList<T>.C# Внедрить интерфейс через делегата

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 в качестве делегата, который реализует эти интерфейсы, но это, кажется, невозможно ...

Эта функция включена в Delphi через implements Ключевое слово для свойств:

property Collection: ICollection read _list implements ICollection; 

Я знаю, что вопросы this и this в принципе те же, но решение наследования для меня невозможно, а также я не могу просто разоблачить интерфейсы как свойства. Это будет работать, даже если немного неудобно использовать, для ICollection<T>, но не для свойства 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.

ответ

1

Если я вас правильно понял, вы должны получить что-то вроде этого

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#.

+0

Но таким образом привязка не будет пытаться использовать динамические свойства ... я действительно нужен объект, который WPF может использовать для привязки, а также получить CollectionChanged от –

+0

Можете ли вы привести пример того, как вы хотите видеть это в разметке xaml? –

+0

Я отредактирую свой вопрос –