2009-07-23 27 views
9

Tôi đang thêm TreeViewItems theo cách thủ công vào mã phía sau và muốn sử dụng DataTemplate để hiển thị chúng nhưng không thể tìm ra cách. Tôi hy vọng sẽ làm một cái gì đó như thế này nhưng các mục được hiển thị dưới dạng tiêu đề trống. Tôi đang làm gì sai?Sử dụng ItemTemplate cho TreeView khi thêm các mục vào mã

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> 

Đằng sau đang

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; } 
    } 
} 

Trả lời

11

ItemTemplate của bạn đang cố gắng để làm cho một "Tên" và "Tuổi" bất động sản trong TextBlocks, nhưng TreeViewItem không có một "Age" bất động sản và bạn không đặt "Tên" của nó.

Vì bạn đang sử dụng một ItemTemplate, không cần phải thêm TreeViewItems vào cây. Thay vào đó, hãy thêm trực tiếp cá thể Cá nhân của bạn:

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

Vấn đề là đối tượng cơ bản của bạn ("Person") không có khái niệm phân cấp, vì vậy không có cách đơn giản để thêm "Joe" tới "Sally". Có một vài tùy chọn phức tạp hơn:

Bạn có thể thử xử lý sự kiện TreeView.ItemContainerGenerator.StatusChanged và chờ cho "Sally" mục được tạo ra, sau đó nhận được một xử lý cho nó và thêm Joe trực tiếp:

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 }); 
    }; 
} 

Hoặc, một giải pháp tốt hơn, bạn có thể giới thiệu các khái niệm hệ thống cấp bậc thành đối tượng "Person" của bạn và sử dụng một HierarchicalDataTemplate để xác định thứ bậc TreeView:

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> 

Mã sản phẩm:

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; } 
    } 
} 

This is a "dữ liệu theo định hướng" cách hơn để hiển thị hệ thống cấp bậc của bạn và một cách tiếp cận IMHO tốt hơn.

+0

Cả hai giải pháp của bạn đều hoạt động. Rất tiếc đã mất quá nhiều thời gian để liên hệ lại với bạn. Cuối cùng tôi đã không sử dụng một cây cuối cùng, thay vào đó thực hiện một hộp danh sách phân cấp tùy chỉnh. –

+1

Hoan hô cho Matt! chỉ là những gì tôi cần (giải pháp thứ hai) –

0

Nó sẽ hoạt động nếu bạn kéo DataTemplate ra khỏi TreeView và đặt nó vào Window.Resources. Như thế này:

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

Đừng quên thêm đúng không gian tên trước người.