ObservableCollection类型的DependencyProperty不绑定

时间:2015-06-11 12:29:21

标签: c# wpf observablecollection dependency-properties

我正在尝试使用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); }
    }

1 个答案:

答案 0 :(得分:1)

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

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

例如,如果您的控件想要执行添加,删除和插入项目和/或索引到集合中的操作,请检查它是否实现IList。如果要观察集合的更改,请检查它是否实现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);
    }
}