目前我正在使用依赖项属性构建自定义控件。此依赖项属性应该是对象列表。问题是,当我将依赖属性声明为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:更正了我的编辑,以便可以看到错误。
答案 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();
}