这个相当复杂,希望我能够清楚地告诉别人帮助我。我有一个对象让我们称之为经理,经理有一个他管理的人的集合,人们都实施IPerson,但不同类型的人有不同的属性。我想在树中显示这个管理器,在管理器节点下我想显示他正在管理的所有项目,这些项目可以从他管理的人员中确定。
因此,计划是使用转换器将人员转换为项目列表。这是XAML:
<HierarchicalDataTemplate DataType="{x:Type ui:Manager}">
<TextBlock Text="{Binding Path=Name}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate.ItemsSource>
<Binding Path="People">
<Binding.Converter>
<configUtil:ProjectListConverter/>
</Binding.Converter>
</Binding>
</HierarchicalDataTemplate.ItemsSource>
</HierarchicalDataTemplate>
我的Person类实现了INotifyPropertyChanged,持有人的列表实现了INotifyCollectionChanged。当我设置treeview ItemsSource时,这个代码很有用,管理器显示了他们的项目列表。
但是,当我向人员列表中添加新人时,TreeView不会更新。当我调试时,我可以看到CollectionChanged正在使用Add操作和添加的项进行触发。 CollectionChanged事件也不是null,所以我知道UI正在观看它。但添加项目时,Converter不会执行。
这是包含IPerson对象的List的Add方法:
public void Add(T item)
{
list.Add(item);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}
我是否以某种方式打破了数据绑定?
我还可以查看哪些其他内容?
转换器只查看人员列表中的每个项目,并确定他们正在处理的项目,并将项目名称添加到输出列表。
答案 0 :(得分:2)
转换器应用于存储集合的属性。因此,只有在集合实例本身发生更改时才会调用它(而不是在集合中的项目发生更改时)。解决这个问题的一种方法是在需要刷新时使集合无效。
使集合属性无效并使转换器代码再次运行的最简单方法是将null
输出集合并重新分配。另一种方法是获取BindingExpression
(通过BindingOperations
)并致电UpdateTarget
。最后,您可以绑定到CollectionView
(或其子类)并在其上调用Refresh
。
如果确实希望彻底解决问题,您可以绑定到自己的ICollectionView
实现,它会根据需要进行过滤并引发事件。