3

TreeViewデータ テンプレートを使用してコレクションを wpf コントロールにバインドしようとしています。コレクション内の各アイテム (Person) には、タイプが car と book の 2 つの異なるコレクション (Cars、Books) も含まれています。

スペースを節約するために関係するオブジェクトの簡単なリストを次に示します。

public class Person
{
  public string Name
  public List<Book> Books;
  public List<Car> Cars;
}

public class Book
{
  public string Title
  public string Author
}

public class Car
{
  public string Manufacturer;
  public string Model;
}

これが私が拘束している方法です

    public MainWindow()
    {
        InitializeComponent();

        this.treeView1.ItemsSource = this.PersonList();
    }

    public List<Person> PersonList()
    {
        List<Person> list = new List<Person>();


        Book eco = new Book { Title = "Economics 101", Author = "Adam Smith"};
        Book design = new Book { Title = "Web Design", Author = "Robins" };

        Car corola = new Car { Manufacturer = "Toyota", Model = "2005 Corola"};
        Car ford = new Car { Manufacturer = "Ford", Model = "2008 Focus"};

        Person john = new Person { Name = "John", Books = new ObservableCollection<Book> { eco, design }, Cars = new ObservableCollection<Car> { corola } };

        Person smith = new Person { Name = "Smith", Books = new ObservableCollection<Book> { eco, design }, Cars = new ObservableCollection<Car> { ford } };

        list.AddRange(new[] {john, smith });
        return list;
    }

ここにXamlコードがあります

<Grid>
    <TreeView  Name="treeView1">
    </TreeView>
</Grid>

ツリーの表示がこのようになることを期待しています。

>John
  >Books
    Economics 101 : Adam Smith
    Web Design    : Robins
  >Cars
    Totota : 2005 Corola
>Smith
  >Books
    Economics 101 : Adam Smith
    Web Design    : Robins
  >Cars
    Ford: 2008 Focus

この記号 > はツリー フォルダを示すために使用され、テンプレートでは考慮されません。

4

3 に答える 3

7

ツリーには 2 つの異なる子コレクションがあるため、少し複雑です。ItemsSourceWPF は、複数の定義を持つシナリオをサポートしていません。したがって、これらのコレクションをCompositeCollectionに結合する必要があります。複合要素 (つまり、Car、Book) の型の一致は自動的に行われます。

XAML では、型の定義に一致する、いわゆるHierarchicalDataTemplatesを定義する必要があります。、、が定義されlocalている名前空間を指す場合、簡略化されたものは次のようになります。BookCarPersonHierarchicalDataTemplates

 <HierarchicalDataTemplate DataType="{x:Type local:Person}" 
                              ItemsSource="{Binding CompositeChildren}">
        <TextBlock Text="{Binding Path=Name}" />
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate DataType="{x:Type local:Book}">
        <TextBlock Text="{Binding Path=Title}" />
        <!-- ... -->
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate DataType="{x:Type local:Car}">
        <TextBlock Text="{Binding Path=Model}" />
        <!-- ... -->
    </HierarchicalDataTemplate>

次に、コレクションをツリー コントロールに接続する必要があります。これを行うにはいくつかの可能性があります。最も簡単なのは、Windowクラスでプロパティを定義し、Binding を定義することです。

<TreeView Items={Binding ElementName=myWindow, Path=Persons}/>

これはあなたを正しい方向に向けるはずですが、私のコードをコンパイルの準備ができていると見なさないでください:-)

于 2010-02-19T20:51:08.303 に答える
3

CompositeCollectionDataContextではないため、子コレクションをにバインドできないことを除いて、良い答えですFreezable。それらはリソースにのみバインドできます。(詳細については、この質問を参照してください。) in を使用するには、現在のコンテキストでプロパティにバインドする必要があるHierarchicalDataTemplateため、 inを使用するのが少し難しくなります。ItemsSource

コレクションの変更通知が必要ない場合は、ビュー モデルにプロパティを簡単に実装できます。

public IEnumerable<object> Items
{
   get { return Books.Concat(Cars); }
}

コレクションの変更通知が必要な場合は、それほど簡単ではありません。

于 2010-02-20T02:19:07.373 に答える
1

が必要ですDataTemplate。そうしないと、WPF はオブジェクトを表示する方法を知りません。

于 2010-02-19T19:25:37.857 に答える