ObservableCollection未在C#WPF中更新Multibinding

时间:2009-09-18 08:07:56

标签: wpf observablecollection multibinding

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

XAML:

<HierarchicalDataTemplate DataType="{x:Type local:GameNode}">
        <HierarchicalDataTemplate.ItemsSource>
            <MultiBinding Converter="{StaticResource combineConverter}">
                <Binding Path="Attributes" />
                <Binding Path="ChildNodes" />
            </MultiBinding>
        </HierarchicalDataTemplate.ItemsSource>
        <TextBlock Text="{Binding Path=Name}" ContextMenu="{StaticResource EntityCtxMenu}"/>
    </HierarchicalDataTemplate>

C#:

public class GameNode
{
    string mName;
    public string Name { get { return mName; } set { mName = value; } }

    GameNodeList mChildNodes = new GameNodeList();
    public GameNodeList ChildNodes { get { return mChildNodes; } set { mChildNodes = value; } }

    ObservableCollection<EntityAttrib> mAttributes = new ObservableCollection<EntityAttrib>();
    public ObservableCollection<EntityAttrib> Attributes { get { return mAttributes; } set { mAttributes = value; } }
}

GameNodeList是一个子类ObservableCollection

1 个答案:

答案 0 :(得分:1)

最好的方法(只有你的EntityAttrib和GameNode是从同一个基类继承的两个不同的类)才会实际定义两个数据模板,如下所示。

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

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

这样更好,因为以后更容易回忆起来。考虑文件系统对象,FileInfo和DirectoryInfo类实际上都是从共享公共属性的FileSystemInfo类派生的。

你应该有一个基类,“BaseGameNode”,里面有一些东西,“GameNode”和“GameEntityAttribNode”都来自“BaseGameNode”。并且它们应该只有一个Children属性,它是BaseGameNode类型的可观察集合,但它的项目实例应该根据需要不同。

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

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

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