3

这个相当复杂,希望我能把这个说清楚,以便有人帮助我。我有一个对象,我们称之为经理,经理有一组他管理的人,这些人都实现了 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。当我设置树视图 ItemsSource 时,此代码效果很好,经理与他们的项目列表一起显示。

但是,当我将新人添加到人员列表时,TreeView 不会更新。当我调试时,我可以看到 CollectionChanged 正在使用 Add 操作和添加的项目触发。CollectionChanged 事件也不为空,所以我知道 UI 正在观看它。但是添加项目时转换器不会执行。

这是保存 IPerson 对象的 List 的 Add 方法:

public void Add(T item)
{
    list.Add(item);
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}

我是否以某种方式破坏了数据绑定?

我还可以检查哪些其他内容?

转换器只是查看人员列表中的每个项目并确定他们正在处理的项目并将项目名称添加到输出列表中。

4

1 回答 1

2

转换器应用于存储集合的属性。因此,只有在集合实例本身发生变化时才会调用它(而不是在集合中的项目发生变化时)。解决此问题的一种方法是在您希望它刷新时使集合无效。

使集合属性无效并导致转换器代码再次运行的最简单方法是null取出集合并重新分配它。另一种方法是获取BindingExpression(via BindingOperations) 并调用UpdateTarget. 最后,您可以改为绑定到一个CollectionView(或其子类)并调用Refresh它。

如果你真的想彻底解决问题,你可以绑定到你自己的实现,ICollectionView它会根据需要进行过滤并引发事件。

于 2009-04-01T18:06:07.180 回答