2016-10-31 4 views
0

Я создал пользовательский элемент управления (FilterPicker), который имеет определенный список как свойство. Это свойство зависимостей, поэтому его можно установить, когда я использую пользовательский элемент управления.Настройка коллекции DependencyProperty из XAML (WPF)

public static readonly DependencyProperty StrategiesProperty = DependencyProperty.Register(
     "Strategies", 
     typeof(List<FilterType>), 
     typeof(FilterPicker), 
     new FrameworkPropertyMetadata 
     { 
      DefaultValue = new List<FilterType> { FilterType.Despike }, 
      PropertyChangedCallback = StrategiesChangedCallback, 
      BindsTwoWayByDefault = false, 
     }); 

Затем я пытаюсь определить этот список в файле .xaml, где я использую этот элемент управления.

<Filtering:FilterPicker Grid.Row="1" Strategy="{Binding Strategy}"> 
      <Filtering:FilterPicker.Strategies> 
       <Filtering1:FilterType>PassThrough</Filtering1:FilterType> 
       <Filtering1:FilterType>MovingAverage</Filtering1:FilterType> 
       <Filtering1:FilterType>Despike</Filtering1:FilterType> 
      </Filtering:FilterPicker.Strategies> 
     </Filtering:FilterPicker> 

Однако, это не работает. StrategiesChangedCallBack никогда не вызывается. Если я устанавливаю его через привязку, он отлично работает - просто не когда я пытаюсь определить его в xaml. Так что это работает:

<Filtering:FilterPicker Grid.Row="1" Strategy="{Binding Strategy}" Strategies="{Binding AllStrategies}"> 

Но не предыдущий фрагмент. Любые идеи о том, что я делаю неправильно?

+3

элементов, добавленных в XAML добавляются к уже существующей коллекции, которые вы установили в качестве значения свойства по умолчанию. Экземпляр коллекции не изменяется, поэтому PropertyChangedCallback не вызывается. Вместо списка вы можете использовать коллекцию, которая реализует интерфейс INotifyCollectionChanged (например, ObservableCollection) и присоединяет обработчик для события CollectionChanged. – Clemens

+1

Кроме того, использование значения по умолчанию для свойства зависимостей типа коллекции потенциально опасно, поскольку все экземпляры класса-владельца по умолчанию будут работать в одном экземпляре коллекции, то есть добавление элементов в свойство Strategies одного фильтра FilterPicker повлияет на свойство все другие FilterPickers. – Clemens

+0

См., Например, [этот ответ] (http://stackoverflow.com/a/9128855/1136211) или [этот] (http://stackoverflow.com/a/19558932/1136211), как работать с INotifyCollectionChanged. – Clemens

ответ

1

От комментариев по моему первоначальному вопросу, я был в состоянии собрать вместе:

  • Действительно проблема была я прислушивался только к изменяемого свойства, а не на объекты в коллекции.
  • Как и было предсказано, у меня были проблемы с ним, работающие в одном экземпляре коллекции.

В конце я изменил свой DependencyProperty на использование IEnumerable, который я определяю как StaticResource в .xaml, который использует FilterPicker UserControl.

DependencyProperty:

public static readonly DependencyProperty StrategiesProperty = DependencyProperty.Register(
     "Strategies", 
     typeof(IEnumerable<FilterType>), 
     typeof(FilterPicker), 
     new FrameworkPropertyMetadata 
     { 
      DefaultValue = ImmutableList<FilterType>.Empty, //Custom implementation of IEnumerable 
      PropertyChangedCallback = StrategiesChangedCallback, 
      BindsTwoWayByDefault = false, 
     }); 

С его помощью:

<Grid.Resources> 
      <x:Array x:Key="FilterTypes" Type="{x:Type Filtering1:FilterType}" > 
       <Filtering1:FilterType>PassThrough</Filtering1:FilterType> 
       <Filtering1:FilterType>MovingAverage</Filtering1:FilterType> 
       <Filtering1:FilterType>Fir</Filtering1:FilterType> 
      </x:Array> 
     </Grid.Resources> 

<Filtering:FilterPicker Grid.Row="1" Strategies="{StaticResource FilterTypes}" /> 
Смежные вопросы