DependencyProperty getter/setter 未被调用 [英] DependencyProperty getter/setter not being called
问题描述
我正在尝试创建一个从标准网格派生的自定义控件.我添加了一个 ObservableCollection 作为自定义控件的 DependencyProperty.但是,它的 get/set 永远不会到达.我可以在创建与 ObservableCollection 一起正常工作的 DependencyProperty 方面有一些指导吗?
I am trying to create a Custom control derived from a standard Grid. I added a ObservableCollection as a DependencyProperty of the Custom control. However, the get/set of it is never reached. Can I have some guidelines in creating a DependencyProperty that works correctly with and ObservableCollection?
public class MyGrid : Grid
{
public ObservableCollection<string> Items
{
get
{
return (ObservableCollection<string>)GetValue(ItemsProperty);
}
set
{
SetValue(ItemsProperty, value);
}
}
public static DependencyProperty ItemsProperty =
DependencyProperty.Register("Items", typeof(ObservableCollection<string>),
typeof(MyGrid), new UIPropertyMetadata(null, OnItemsChanged));
}
推荐答案
我建议不要使用 ObservableCollection 作为 Items
依赖属性的类型.
I would suggest not to use ObservableCollection as the type of an Items
dependency property.
这里有一个 ObservableCollection 的原因(我猜)是为了让 UserControl 在分配属性值时附加一个 CollectionChanged
处理程序.但是 ObservableCollection 太具体了.
The reason for having an ObservableCollection here (I guess) is to enable the UserControl to attach a CollectionChanged
handler when the property value is assigned. But ObservableCollection is too specific.
WPF 中的方法(例如在 ItemsControl.ItemsSource) 是定义一个非常基本的接口类型(如IEnumerable
),当属性被赋值时,找出值集合是否实现了某些更具体的接口.这至少是 INotifyCollectionChanged 在这里,但是该集合还可能实现 ICollectionView 和 INotifyPropertyChanged.所有这些接口都不是强制性的,这将使您的依赖属性能够绑定到各种集合,从普通数组到复杂的 ItemCollection.
The approach in WPF (e.g. in ItemsControl.ItemsSource) is to define a very basic interface type (like IEnumerable
) and when the property is assigned a value, find out if the value collection implements certain more specific interfaces. This would at least be INotifyCollectionChanged here, but the collection might also implement ICollectionView and INotifyPropertyChanged. All these interfaces wouldn't be mandatory and that would enable your dependency property to bind to all sorts of collections, starting with a plain array up to a complex ItemCollection.
您的 OnItemsChanged
属性更改回调将如下所示:
Your OnItemsChanged
property change callback would then look like this:
private static void OnItemsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
MyGrid grid = obj as MyGrid;
if (grid != null)
{
var oldCollectionChanged = e.OldValue as INotifyCollectionChanged;
var newCollectionChanged = e.NewValue as INotifyCollectionChanged;
if (oldCollectionChanged != null)
{
oldCollectionChanged.CollectionChanged -= grid.OnItemsCollectionChanged;
}
if (newCollectionChanged != null)
{
newCollectionChanged.CollectionChanged += grid.OnItemsCollectionChanged;
// in addition to adding a CollectionChanged handler
// any already existing collection elements should be processed here
}
}
}
private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// handle collection changes here
}
这篇关于DependencyProperty getter/setter 未被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!