4

私は XAML とデータバインディングにかなり慣れていないので、これが誰かにとって簡単な質問になることを願っています...

次のような構造を持つデータ バインディングを使用して TreeView を構築しようとしています。

  • カテゴリー
    • 項目名
    • 項目名
  • カテゴリー
    • 項目名

これまでのところ、とても良い - 私はそれを行うことができます. 次に、Item ノードを展開して、その項目の詳細を表示できるようにします。コード ビハインドでツリーを手動で構築する場合、これは正常に機能しますが、代わりにデータ バインディングを使用したいと考えています。私はほとんどこれを機能させていますが、現在のように、ノードを選択できないか、折りたたまれたときにアイテム名だけを表示し、展開してさらに表示できる TreeViewItem のようにノードを動作させることができません-- 私の場合は、データを含むカスタム定義のグリッドです。

私の XAML コードの簡単なサンプルを次に示します。

<DataTemplate x:Key="ItemDataTemplate">
    <TreeViewItem Header="{Binding Path=ItemName}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>

            <TextBlock Grid.Row="0" Grid.Column="0" Text="Price" />
            <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Price}"/>

            <TextBlock Grid.Row="1" Grid.Column="0" Text="Description" />
            <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}"/>

            <TextBlock Grid.Row="2" Grid.Column="0" Text="Qty on Hand" />
            <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Qty}"/>
        </Grid>
    </TreeViewItem>
</DataTemplate>

<HierarchicalDataTemplate x:Key="CategoryDataTemplate" ItemsSource="{Binding Path=Categories}" ItemTemplate="{StaticResource ItemDataTemplate}">
    <TextBlock Text="{Binding Path=CategoryName}"/>
</HierarchicalDataTemplate>

この単純化された例に基づいて、コード ビハインドで定義されたオブジェクトは次のようになります。

public class Category
{
    public ObservableCollection<Item> Items {get; private set;}
    public string CategoryName { get; set; }

    //constructor and methods here
}
public class Item
{
    public string ItemName {get; private set;}
    public decimal Price { get; private set; }
    public string Description {get; private set; }
    public int Qty {get; set;}

    //constructor and methods here
}

この質問とスタックオーバーフローの回答を読んだ後、ノードを選択したい場合、テンプレートを TreeViewItem にすることはできないことがわかります。TreeViewItem タグを削除して、ノードを選択できるグリッドに直行しようとしましたが、ノードを ItemName (ヘッダー テキスト) だけに折りたたむことができなくなりました。

すごく近い気がする...何が欠けているの?

4

1 に答える 1

1

したがって、必要なのは、アイテムの「子」がそれ自体であり、より多くの情報が表示されている場合でも、アイテムに子ノードが多いように見せることです。

それを行う最も正しい方法は、次のようにItemDataTemplateでエキスパンダーを使用することです。

<DataTemplate x:Key="ItemDataTemplate">
    <Expander Header="{Binding Path=ItemName}" >
        <Grid>
            <Grid.ColumnDefinitions>
                ...
            <Grid.RowDefinitions>
                ...

            <TextBlock Grid.Row="0" Grid.Column="0" Text="Price" />
            <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Price}"/>

            <TextBlock ...
        </Grid>
    </TreeViewItem>
</DataTemplate>

エクスパンダは標準のTreeViewItemとまったく同じようには見えませんが、エクスパンダ用に独自のテンプレートを作成することで修正できます。

さて、もう少しハッキーな方法は、ItemクラスにItemのリストを作成することです。ここで、各Itemはそれ自体を唯一のリスト要素として公開します。次に、ItemDataTemplateは、別のより詳細な「ItemDetailsTemlate」を参照するHierarchicalDataTemplateである必要があります。

public class Item
{
    ...

    public List<Item> InfoWrapper
    {
        get { return new List<Item>() { this }; }
    }
}

Xaml:

<DataTemplate x:Key="ItemDetailsTemplate">
    <Grid>
        <Grid.ColumnDefinitions>
            ...
        <Grid.RowDefinitions>
            ...

        <TextBlock Grid.Row="0" Grid.Column="0" Text="Price" />
        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Price}"/>

        <TextBlock ...
    </Grid>
</DataTemplate>

<HierarchicalDataTemplate x:Key="ItemDataTemplate" ItemsSource="{Binding Path=InfoWrapper}" ItemTemplate="{StaticResource ItemDetailsTemplate}" >
    <TextBlock Text="{Binding Path=ItemName}"/>
</HierarchicalDataTemplate>
于 2012-12-20T23:12:06.360 に答える