2009-07-23 3 views
9

TreeViewItemsを手作業でコードに追加していますが、DataTemplateを使用して表示する方法は分かりません。私はこのようなことをしたいと思っていますが、項目は空のヘッダとして表示されます。私は間違って何をしていますか?コード内に項目を追加するときにItemTemplateをTreeViewに使用する

XAML

<Window x:Class="TreeTest.WindowTree" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="WindowTree" Height="300" Width="300"> 
    <Grid> 
     <TreeView Name="_treeView"> 
      <TreeView.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <TextBlock Text="{Binding Path=Name}" /> 
         <TextBlock Text="{Binding Path=Age}" /> 
        </StackPanel> 
       </DataTemplate> 
      </TreeView.ItemTemplate> 
     </TreeView> 
    </Grid> 
</Window> 
コードの後ろ

using System.Windows; 
using System.Windows.Controls; 

namespace TreeTest 
{ 
    public partial class WindowTree : Window 
    { 
     public WindowTree() 
     { 
      InitializeComponent(); 

      TreeViewItem itemBob = new TreeViewItem(); 
      itemBob.DataContext = new Person() { Name = "Bob", Age = 34 }; 

      TreeViewItem itemSally = new TreeViewItem(); 
      itemSally.DataContext = new Person() { Name = "Sally", Age = 28 }; ; 

      TreeViewItem itemJoe = new TreeViewItem(); 
      itemJoe.DataContext = new Person() { Name = "Joe", Age = 15 }; ; 
      itemSally.Items.Add(itemJoe); 

      _treeView.Items.Add(itemBob); 
      _treeView.Items.Add(itemSally); 
     } 
    } 

    public class Person 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
    } 
} 

答えて

11

あなたのItemTemplateには、テキストブロック内の「名前」と「年齢」プロパティをレンダリングしようとしているが、ツリービューアイテムは、「年齢」性質を持っていませんあなたはその "名前"を設定していません。

ItemTemplateを使用しているため、TreeViewItemをツリーに追加する必要はありません。代わりに、直接あなたのPersonインスタンスを追加します。

_treeView.Items.Add(new Person { Name = "Sally", Age = 28}); 

問題を、もちろん、あなたの基礎となるオブジェクト(「人物」)は階層の任意の概念を持っていないということですので、「ジョー」を追加する簡単な方法はありません"サリー"に。より複雑なオプションがいくつかあります:

あなたはそれへのハンドルを取得し、直接ジョーを追加し、TreeView.ItemContainerGenerator.StatusChangedイベントを処理しようとして生成される「サリー」の項目を待つこともできます

public Window1() 
{ 
    InitializeComponent(); 
    var bob = new Person { Name = "Bob", Age = 34 }; 
    var sally = new Person { Name = "Sally", Age = 28 }; 

    _treeView.Items.Add(bob); 
    _treeView.Items.Add(sally); 

    _treeView.ItemContainerGenerator.StatusChanged += (sender, e) => 
    { 
     if (_treeView.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated) 
      return; 

     var sallyItem = _treeView.ItemContainerGenerator.ContainerFromItem(sally) as TreeViewItem; 
     sallyItem.Items.Add(new Person { Name = "Joe", Age = 15 }); 
    }; 
} 

あるいは、よりよい解決策、あなたは「人」オブジェクトに階層概念を導入し、ツリービューの階層を定義するためにHierarchicalDataTemplateを使用することができます。

XAML:

<Window x:Class="TreeTest.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="WindowTree" Height="300" Width="300"> 
    <Grid> 
     <TreeView Name="_treeView"> 
      <TreeView.ItemTemplate> 
       <HierarchicalDataTemplate ItemsSource="{Binding Subordinates}"> 
        <StackPanel Orientation="Horizontal"> 
         <TextBlock Text="{Binding Path=Name}" /> 
         <TextBlock Text="{Binding Path=Age}" /> 
        </StackPanel> 
       </HierarchicalDataTemplate> 
      </TreeView.ItemTemplate> 
     </TreeView> 
    </Grid> 
</Window> 

CODE:

using System.Collections.Generic; 
using System.Windows; 

namespace TreeTest 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
      var bob = new Person { Name = "Bob", Age = 34 }; 
      var sally = new Person { Name = "Sally", Age = 28 }; 

      _treeView.Items.Add(bob); 
      _treeView.Items.Add(sally); 
      sally.Subordinates.Add(new Person { Name = "Joe", Age = 15 }); 
     } 

    } 
    public class Person 
    { 
     public Person() 
     { 
      Subordinates = new List<Person>(); 
     } 

     public string Name { get; set; } 
     public int Age { get; set; } 
     public List<Person> Subordinates { get; private set; } 
    } 
} 

これはあなたの階層とより良いアプローチの私見を表示するためのより多くの「データ指向」の方法です。

+0

両方のソリューションが機能します。あなたに戻ってくるのにずっと時間をかけて申し訳ありません。私は最後にツリーを使用せず、代わりにカスタムの階層リストボックスを実装しました。 –

+1

ママのためにはじめて!ちょうど私が必要なもの(2番目のソリューション) –

0

DataTemplateをTreeViewから取り出してWindow.Resourcesに配置すると機能します。このように:

<Window.Resources>  
    <DataTemplate DataType={x:type Person}> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding Path=Name}" /> 
      <TextBlock Text="{Binding Path=Age}" /> 
     </StackPanel> 
    </DataTemplate> 
</Window.Resources> 

Personの前に正しい名前空間を追加することを忘れないでください。

関連する問題