0

次のように構造化された一連のデータがあります。

 ItemA.GroupA
 ItemB.GroupA
 ItemC.GroupB
 ItemD.GroupC

次のように、データを WPF ツリー ビューに表示する必要があります。

グループA

--- アイテムA

--- アイテムB

グループB

--- アイテムC

グループC

--- アイテムD

個別の値で葉をグループ化するには、どの XAML を使用できますか? たとえば、GroupA.ItemA であるコレクションに複数のアイテムが存在する可能性がありますが、ノードとリーフを 1 回だけ提示したいと考えています。

4

2 に答える 2

1

私はここでitowlsonに同意しません。これは厄介な問題ではなく、HierarchicalDataTemplateこの種のことのために作られました。パターンやビューモデル、その他の不要な難読化に無計画に飛び込む前に、2つのクラスと1つのLinq GroupByステートメントで問題を解決できることを考慮してください。

クラスは次のとおりです。

public class GroupItem
{
    public string Name
    {
        get;
        private set;
    }

    public string Group
    {
        get;
        private set;
    }

    public GroupItem(string name, string group)
    {
        Name = name;
        Group = group;
    }
}

public class Group
{
    public IEnumerable<GroupItem> Children
    {
        get;
        set;
    }

    public string Name
    {
        get;
        private set;
    }

    public Group(string name)
    {
        Name = name;
    }
}

ここまでは順調ですね。必要なすべてのデータを保持するための2つの簡単なクラスがあります。名前とグループは文字列として保存されます。AGroup にはのコレクションがありGroupItemます。今あなたのコードのためにWindow

public partial class DistinctLeaves : Window
{
    public ObservableCollection<GroupItem> Items
    {
        get;
        set;
    }

    public IEnumerable<Group> Groups
    {
        get;
        set;
    }

    public DistinctLeaves()
    {
        Items = new ObservableCollection<GroupItem>();

        Items.Add(new GroupItem("Item A", "Group A"));
        Items.Add(new GroupItem("Item B", "Group A"));
        Items.Add(new GroupItem("Item C", "Group B"));
        Items.Add(new GroupItem("Item D", "Group C"));

        Groups = Items.
            GroupBy(i => i.Group).
            Select(g => new Group(g.Key) { Children = g });

        InitializeComponent();
    }
}

繰り返しになりますが、これはgroup-by行を除くすべての定型文です。その声明はさらに調査する価値があります。これにより、アイテムコレクションがプロパティに従ってグループ化されGroupます。アイテムがグループ化されたら、Groupクラスの新しいインスタンスを作成します。グループのnameプロパティ(キー)を渡し、子をグループ自体に設定します。

最後に、 :Windowを使用するのXAMLを次に示します。HierarchicalDataTemplate

<Window x:Class="TestWpfApplication.DistinctLeaves"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DistinctLeaves" Height="300" Width="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
    <TreeView ItemsSource="{Binding Groups}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Name}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</Grid>

そしてここに結果があります:

代替テキストhttp://img339.imageshack.us/img339/8555/distinctleaves.jpg

于 2010-04-12T22:27:28.130 に答える
1

少なくとも自然な方法では、XAML でそれを行うことはできません。より良いアプローチは、ビュー モデル(データを表示しやすい方法で表すクラス) を導入することです。これにより、XAML をシンプルかつ自然に保つことができます。

したがって、あなたの場合、 ItemX コレクションをラップし、グループとその個別のメンバーを公開するクラスがあります。

public class MyItemsViewModel
{
  public IList<MyGroupViewModel> Groups { get; }
}

public class MyGroupViewModel
{
  public string GroupName { get; }
  public IList<MyItem> DistinctItems { get; }
}

その後、HierarchicalDataTemplate はほぼ自動的に削除されます。さらなる利点として、ビュー モデル クラスは単なるデータ オブジェクトであるため、それらを自動テスト下に置くことができますが、複雑な XAML には手動テストが必要です。

于 2010-04-12T21:16:56.700 に答える