2009-07-23 2 views
9

TreeViewItems를 코드 숨김으로 수동으로 추가하고이를 표시하기 위해 DataTemplate을 사용하려고하지만 방법을 알 수 없습니다. 이런 일을하기를 바라고 있지만 항목은 빈 헤더로 표시됩니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?코드에 항목을 추가 할 때 TreeView에 ItemTemplate 사용

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을이 "이름"과 TextBlocks에서 "나이"속성을 렌더링하려고하지만 TreeViewItem는 "나이"속성이 없습니다 당신은 그 "이름"을 설정하지 않습니다.

ItemTemplate을 사용 중이므로 TreeViewItem을 트리에 추가 할 필요가 없습니다. 대신, 직접 사람 인스턴스를 추가 :

_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

매트 만세! 내가 필요한 것 (두 번째 해결책) –

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> 

사람 앞에 올바른 네임 스페이스를 추가하는 것을 잊지 마십시오.

관련 문제