依赖属性:IEnumerable<>工作,ICollection<>不工作

时间:2018-02-22 09:47:53

标签: c# wpf dependency-properties

目前我正在使用依赖项属性构建自定义控件。此依赖项属性应该是对象列表。问题是,当我将依赖属性声明为IEnumerable<>时,它可以工作并调用回调方法。但是当我选择ICollection<>IList<>时,依赖属性的回调方法不会被调用。具有依赖项属性的自定义控件位于自定义控件库中,并由我当前的测试项目引用。

我的自定义控件中的依赖项属性实现:

private static readonly FrameworkPropertyMetadata depPropMetaData =
    new FrameworkPropertyMetadata(new PropertyChangedCallback(OnStructureChanged));

public static readonly DependencyProperty TreeListStructureProperty =
    DependencyProperty.Register(
        "TreeListStructure",
        typeof(IEnumerable<ITreeListStructure>),
        typeof(TreeListView),
        depPropMetaData);

public IEnumerable<ITreeListStructure> TreeListStructure
{
    get { return (IEnumerable<ITreeListStructure>)this.GetValue(TreeListStructureProperty); }
    set { this.SetValue(TreeListStructureProperty, value); }
}

private static void OnStructureChanged(
    DependencyObject depObj, DependencyPropertyChangedEventArgs eventArgs)
{
    ; //Breakpoint here
}

在我的带有MainView窗口的测试项目中,我只需绑定DataContext,如下所示:

TestingWrapperViewModel testingVM = new TestingWrapperViewModel();
testingVM.GenerateTestItems(5);
this.DataContext = testingVM;

完成MainView.xaml中的Binding:

<TreeListView:TreeListView TreeListStructure="{Binding ViewModelList}">

TestingWrapperViewModel-class只包含以下内容:

class TestingWrapperViewModel : INotifyPropertyChanged
{
    private List<TestingViewModel> _viewModelList = new List<TestingViewModel>();

    public List<TestingViewModel> ViewModelList
    {
        get { return this._viewModelList; }
        set
        {
            this._viewModelList = value;
            OnPropertyChanged("ViewModelList");
        }
    }

    public void GenerateTestItems(uint nAmount)
    {
        //Just generate some objects for testing
    }

    //INotifyPropertyChanged Implemenation
}

TestingViewModel实现了ITreeListStructure-Interface:

class TestingViewModel : ITreeListStructure, INotifyPropertyChanged

我刚刚列出的代码触发OnStructureChanged事件,并返回DependencyPropertyChangedEventArgs中指定数量的元素。但是当我将依赖项属性声明中的IEnumerable<>更改为ICollection<>IList<>List<>时,回调方法根本不会被调用。

我想了解为什么这不起作用。我希望有人可以解释一下。

谢谢,

Heenne

编辑: 注释中的格式错误,此处添加了代码:

public void GenerateTestItems(uint nAmount)
    {
        List<TestingViewModel> temp = new List<TestingViewModel>();
        for (uint nCounter = 0; nCounter < nAmount; nCounter++)
        {
            temp.Add(new TestingViewModel("TestObject" + nCounter.ToString()));
        }

        ICollection<ITreeListStructure> test1 = temp; //ERROR
        IEnumerable<ITreeListStructure> test2 = temp;

        this.ViewModelList = temp;
    }

EDIT2:更正了我的编辑,以便可以看到错误。

1 个答案:

答案 0 :(得分:1)

List<TestingViewModel>类型与ICollection<ITreeListStructure>IList<ITreeListStructure>的作业不兼容:

IEnumerable<ITreeListStructure> x = ViewModelList; // ok
ICollection<ITreeListStructure> y = ViewModelList; // not ok.

这是因为IEnumerable<out T>是协变的,ICollection<T>等不是。

有关详细信息,请参阅this question

为了访问依赖项属性中的集合,您应该使用LINQ:

using System.Linq;
...

private static void OnStructureChanged(
    DependencyObject depObj, DependencyPropertyChangedEventArgs eventArgs)
{
    var tls = (IEnumerable<ITreeListStructure>)eventArgs.NewValue;
    var count = tls.Count();
}