ObservableCollection 类型的 DependencyProperty 不绑定

DependencyProperty of type ObservableCollection doesn't bind

我正在尝试使用 DependencyProperty 制作自定义控件。 但是我无法将 ObservableCollection 绑定到控件。 当我使用 Enumerable 时没有问题。但是我需要将项目添加到集合中,所以我唯一的选择是 ObservableCollection.

创建授权:

AuthorizationsDest = new ObservableCollection<Authorization>();
        AuthorizationsDest.Add(new Authorization() { Key = "Test1", Description = "Test1", ObjectState = ObjectState.UnModified });
    }

xaml中的自定义控件

<customControls:ListBoxEditLookup ItemsSource="{Binding Authorizations}" DisplayMember="Description" DestinationList="{Binding AuthorizationsDest}" />

DependencyProperty:

[Description("Binded destination list"), Category("Data")]
    public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("DestinationList", typeof(ObservableCollection<HrdEntity>), typeof(ListBoxEditLookup), new UIPropertyMetadata(null));
    public ObservableCollection<HrdEntity> DestinationList
    {
        get
        {
            return GetValue(ItemsProperty) as ObservableCollection<HrdEntity>;
        }
        set { SetValue(ItemsProperty, value); }
    }

根据对您问题的评论回复,我认为我们已经意识到在您的依赖项 属性 上使用特定的具体集合类型会导致问题,您应该考虑使用如下接口IEnumerable 代替。继续阅读以获得更详细的解释。


使用 IEnumerable 接口作为自定义控件中集合依赖属性的类型通常是个好主意。它是每个集合实现的基本接口,因为它允许 foreach 循环在它们上面 运行。设置依赖项 属性 后,您可以检查该值以查看它是否在您的控制范围内实现了您关心的其他接口。

例如,如果您的控件想要向集合中添加、删除和插入项目 and/or 索引,请检查它是否实现了 IList. If you want to observe the collection for changes, check to see if it implements INotifyCollectionChanged.

考虑维护对类型化为您需要访问的接口的集合的私有引用。例如:

private IList mItemsAsList;
private INotifyCollectionChanged mItemsAsObservable;

// Call when the value of ItemsProperty changes
private void OnItemsChanged(IEnumerable newValue)
{
    if (mItemsAsObservable != null)
    {
        mItemsAsObservable.CollectionChanged -= Items_CollectionChanged;
    }

    mItemsAsList = newValue as IList;
    mItemsAsObservable = newValue as INotifyCollectionChanged;

    if (mItemsAsObservable != null)
    {
        mItemsAsObservable.CollectionChanged += Items_CollectionChanged;
    }
}

private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // Do stuff in response to collection being changed
}

如果您的控件有某些要求(不是可选的),如果不满足这些要求,您总是可以在 属性 更改的回调中抛出一个 ArgumentException。例如,如果您必须能够向集合中添加新项目:

mItemsAsList = newValue as IList;
if (newValue != null && (mItemsAsList == null || mItemsAsList.IsReadOnly || mItemsAsList.IsFixedSize))
{
    throw new ArgumentException("The supplied collection must implement IList, not be readonly, and have a variable size.", "newValue");
}

一旦您对集合有专门的引用,您就可以根据实现的接口来限制您的功能。例如,假设您要添加一个新项目:

private void AddItem(object item)
{
    // Make sure to check IsFixedSize because some collections, such as Array,
    // implement IList but throw an exception if you try to call Add on them.
    if (mItemsAsList != null && !mItemsAsList.IsReadOnly && !mItemsAsList.IsFixedSize)
    {
        mItemsAsList.Add(item);
    }
}