从XAML(WPF)设置集合DependencyProperty
问题描述:
我创建了一个用户控件(FilterPicker
),它具有某个列表作为属性。这是一个依赖项属性,因此可以在使用用户控件时进行设置。从XAML(WPF)设置集合DependencyProperty
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}">
但不是以前的代码片段。关于我在做什么的任何想法都是错误的?
答
从我原来的问题的评论,我能够拼凑一起:
- 事实上,问题是,我只是听着财产被改变,而不是集合中的对象。
- 正如我预测的那样,它在同一个集合实例上运行时遇到问题。
最后,我将我的DependencyProperty更改为使用IEnumerable,我在使用FilterPicker UserControl的.xaml中将其定义为StaticResource。
的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}" />
在XAML中添加的元素被添加到现有的集合,它已设置为属性的默认值。集合实例不会更改,因此不会调用PropertyChangedCallback。您可以使用实现INotifyCollectionChanged接口(例如ObservableCollection)的集合,并为其CollectionChanged事件附加处理程序,而不是List。 – Clemens
除此之外,对集合类型依赖项属性使用默认值有潜在危险,因为拥有的类的所有实例将默认在相同的集合实例上操作,即向一个FilterPicker的Strategies属性中添加元素将影响属性所有其他FilterPickers。 – Clemens
有关如何处理INotifyCollectionChanged,请参阅示例[此答案](http://*.com/a/9128855/1136211)或[this one](http://*.com/a/19558932/1136211)。 – Clemens