1

我有一个 TreeView,它从数据绑定的 ObservableCollections 创建其所有项目。我有一个 GameNode 对象的层次结构,每个对象都有两个 ObservableCollections。一个集合具有 EntityAttrib 对象,另一个具有 GameNode 对象。您可以说 GameNode 对象代表文件夹,而 EntityAttrib 代表文件。为了在同一个 TreeView 中同时显示属性和 GameNode,我使用了多重绑定。这一切在启动时都可以正常工作,但是当我在层次结构中的某处添加新的 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 的子类

4

1 回答 1

1

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

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

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

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

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

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

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

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

于 2009-09-18T08:27:19.577 回答