1

データバインドされた ObservableCollections からすべてのアイテムを作成する TreeView があります。GameNode オブジェクトの階層があり、各オブジェクトには 2 つの ObservableCollections があります。1 つのコレクションには EntityAttrib オブジェクトがあり、もう 1 つのコレクションには GameNode オブジェクトがあります。GameNode オブジェクトはフォルダーを表し、EntityAttrib はファイルを表すと言えます。同じ TreeView に attrib と GameNode の両方を表示するには、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 です

4

1 に答える 1

1

最善の方法 (EntityAttrib と GameNode が同じ基本クラスから継承された 2 つの異なるクラスである場合のみ) は、実際には以下のように 2 つのデータ テンプレートを定義することです。

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

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

後で思い出すのが簡単なので、これはより良いです。ファイル システム オブジェクトを考えてみましょう。FileInfo クラスと DirectoryInfo クラスの両方が、実際には、共通のプロパティを共有する FileSystemInfo クラスから派生しています。

ベースクラス "BaseGameNode" が必要であり、その中に何か "GameNode" と "GameEntityAttribNode" があり、どちらも "BaseGameNode" から派生しています。また、タイプ BaseGameNode の監視可能なコレクションである Children プロパティを 1 つだけ持つ必要がありますが、そのアイテム インスタンスは必要に応じて異なる必要があります。

区別するものがある場合は、複数のテンプレートを定義できます。タイプは、ノードの子に対して自動的に選択されます。

バインドした値は、依存関係プロパティではなく、変更時に通知されるため、更新されません。コレクションの参照/インスタンスが変更されない限り、マルチバインディングはコレクション変更イベントをまったく検出しないためです。コレクション内のアイテムを変更しても、属性/プロパティの実際のインスタンスは変わりません。

ItemsSource = コレクションをバインドすると、その ItemsSource が CollectionChange イベントをリッスンし、それに応じて項目を更新します。

于 2009-09-18T08:27:19.577 に答える