ItemsSource + Converter + Treeview无法更新

3
这个问题相对复杂,希望我能够清晰地解释。 我有一个对象,让我们称之为 Manager,Manager 拥有一组被其管理的人员,这些人都实现了 IPerson 接口,但是不同类型的人具有不同的属性。 我想在树形结构中显示这个经理,并在经理节点下显示他正在管理的所有项目,这可以通过管理的人员确定。
因此,计划使用转换器将 person 转换为项目列表。以下是 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正在监视它。但是,当添加项时,转换器不执行。
以下是保存IPerson对象的列表的Add方法:
public void Add(T item)
{
    list.Add(item);
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}

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

还有哪些方面可以检查?

转换器只是查看People列表中的每个项目,并确定他们正在工作的项目,并将项目名称添加到输出列表中。

1个回答

2
转换器应用于存储集合的属性。因此,仅当集合实例本身更改时才会调用它(而不是更改集合中的项目)。解决这个问题的一种方法是在想要刷新它时使集合无效。
使集合属性无效并再次运行转换器代码的最简单方法是将集合设为null,然后重新分配它。另一种方法是获取BindingExpression(通过BindingOperations),并调用UpdateTarget。最后,您可以绑定到CollectionView(或其子类)并在其上调用Refresh
如果您真的想干净地解决问题,您可以绑定到自己实现的ICollectionView,该视图执行过滤并根据需要引发事件。

我认为我理解你告诉我的要做什么,但我不确定如何在 hierarchicalDataTemplate 中实现。如果我理解正确,我想将 People 属性包装在 CollectionView 中,并在集合更改时刷新 CollectionView。一些示例代码会很有帮助。 - Kelly
谢谢您的帮助,我通过将我的人员列表包装在一个 ObservableCollection 的项目中,订阅了人员集合更改事件并更新自身,现在它可以工作了。 - Kelly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接