ObservableCollection未更新C#WPF中的多重绑定

ObservableCollection未更新C#WPF中的多重绑定,wpf,observablecollection,multibinding,Wpf,Observablecollection,Multibinding,我有一个树状视图,它从数据绑定的ObservableCollections创建所有项目。我有一个GameNode对象的层次结构,每个对象有两个可观的集合。一个集合具有EntityAttrib对象,另一个集合具有GameNode对象。可以说GameNode对象表示文件夹,EntityAttrib表示文件。要在同一个树状视图中显示attrib和GameNodes,我使用多重绑定。 这一切都可以在启动时正常工作,但当我在层次结构中的某个位置添加新的GameNode时,TreeView不会更新。我在我的

我有一个树状视图,它从数据绑定的ObservableCollections创建所有项目。我有一个GameNode对象的层次结构,每个对象有两个可观的集合。一个集合具有EntityAttrib对象,另一个集合具有GameNode对象。可以说GameNode对象表示文件夹,EntityAttrib表示文件。要在同一个树状视图中显示attrib和GameNodes,我使用多重绑定。 这一切都可以在启动时正常工作,但当我在层次结构中的某个位置添加新的GameNode时,TreeView不会更新。我在我的转换器方法中设置了一个断点,但在添加新的GameNode时没有调用它。ObservableCollection似乎没有通知MultiBinding更改。如果我注释掉多重绑定并只绑定GameNode集合,它将按预期工作

XAML:


C#:

公共类游戏节点
{
字符串mName;
公共字符串名称{get{return mName;}set{mName=value;}}
GameNodeList mChildNodes=新GameNodeList();
公共游戏节点列表子节点{get{return mChildNodes;}set{mChildNodes=value;}}
ObservableCollection mAttributes=新的ObservableCollection();
公共ObservableCollection属性{get{return mAttributes;}set{mAttributes=value;}}
}
GameNodeList是一个子类ObservableCollection

最好的方法(仅当EntityAttrib和GameNode是从同一基类继承的两个不同类时)实际上是定义两个数据模板,如下所示

<HierarchicalDataTemplate DataType="{x:Type local:GameNode}">        

<HierarchicalDataTemplate DataType="{x:Type local:EntityAttrib}">        

这是更好的,因为它更容易回忆以后。考虑文件系统对象,FiLeFipe和DirectoyInter类实际上都是从共享公共属性的FraseStimeFipe类派生的。

您应该有一个基类“BaseGameNode”,其中有一些东西,“GameNode”和“GameEntityAttribNode”都派生自“BaseGameNode”。它们应该只有一个子属性,即BaseGameNode类型的可观察集合,但其项实例应该根据需要而有所不同

您可以定义多个模板,只要它们有区别,就会自动为节点的子节点选择类型

您绑定的值不会刷新,因为它们不是依赖项属性,也不会在更改时通知。因为除非集合的引用/实例发生更改,否则多重绑定根本不会检测集合更改事件。更改集合中的项目时,属性/属性的实际实例保持不变

当您绑定ItemsSource=collection时,ItemsSource将侦听CollectionChange事件并相应地更新项目。

最好的方法(仅当您的EntityAttrib和GameNode是从同一基类继承的两个不同类时)是实际定义两个数据模板,如下所示

<HierarchicalDataTemplate DataType="{x:Type local:GameNode}">        

<HierarchicalDataTemplate DataType="{x:Type local:EntityAttrib}">        

这是更好的,因为它更容易回忆以后。考虑文件系统对象,FiLeFipe和DirectoyInter类实际上都是从共享公共属性的FraseStimeFipe类派生的。

您应该有一个基类“BaseGameNode”,其中有一些东西,“GameNode”和“GameEntityAttribNode”都派生自“BaseGameNode”。它们应该只有一个子属性,即BaseGameNode类型的可观察集合,但其项实例应该根据需要而有所不同

您可以定义多个模板,只要它们有区别,就会自动为节点的子节点选择类型

您绑定的值不会刷新,因为它们不是依赖项属性,也不会在更改时通知。因为除非集合的引用/实例发生更改,否则多重绑定根本不会检测集合更改事件。更改集合中的项目时,属性/属性的实际实例保持不变


绑定ItemsSource=collection时,ItemsSource将侦听CollectionChange事件并相应地更新项目。

我不明白这有什么帮助。对于多重绑定,我仍然会遇到同样的问题。实际上,我有一个HierarchycalDataTemplate用于EntityAttrib类型以不同的颜色显示它们。您的转换器根本不会被第二次调用,因为只有在创建节点时才会被调用。因为您的多重绑定不会检测到可观察集合内的更改,而是ItemsSource会检测集合更改并刷新自身。也许我很愚蠢,但我不明白这一点。我不是在GameNode中更改某些内容,而是将GameNode添加到集合中,因此集合已更改,应该会发送一个事件。您说过ItemsSource侦听CollectionChange,但ItemsSource是多重绑定,而多重绑定又是集合。是的,ItemsSource侦听事件,但您的转换器仅在属性或ChildNodes实例更改时调用,而不是在它们触发集合更改事件时调用。这是什么意思“如果属性或ChildNodes实例发生更改”?添加项目是否会更改它们,或者您的意思是我将它们更改为一个完全不同的集合对象?我尝试将GameNode设置为INotifyPropertyChanged并手动触发PropertyChange(“ChildNodes”)在我向ChildNodes添加了一个新的GameNode之后。这确实调用了我的转换器并更新了TreeView。我不明白这有什么帮助。多重绑定仍然会有同样的问题。我确实有一个HierarchycalDataTemplate,用于EntityAttrib类型以不同的颜色显示它们。您的转换器根本不会被第二次调用,请注意因为只有在创建节点时才会调用它。因为多重绑定不会检测到可观察集合内的更改,而是检测集合更改并刷新自身的ItemsSource
<HierarchicalDataTemplate DataType="{x:Type local:GameNode}">        

<HierarchicalDataTemplate DataType="{x:Type local:EntityAttrib}">