DependencyProperty getter/setter 未被调用 [英] DependencyProperty getter/setter not being called

查看:30
本文介绍了DependencyProperty getter/setter 未被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个从标准网格派生的自定义控件.我添加了一个 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 在这里,但是该集合还可能实现 ICollectionViewINotifyPropertyChanged.所有这些接口都不是强制性的,这将使您的依赖属性能够绑定到各种集合,从普通数组到复杂的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆