2009-07-23 12 views
9

में आइटम जोड़ते समय TreeTiew के लिए आइटम टेम्पलेट का उपयोग करना मैं मैन्युअल रूप से कोड में TreeViewItems जोड़ रहा हूं और उन्हें प्रदर्शित करने के लिए डेटा टेम्पलेट का उपयोग करना चाहता हूं लेकिन यह पता नहीं लगा सकता कि कैसे। मैं ऐसा कुछ करने की उम्मीद कर रहा हूं लेकिन आइटम खाली हेडर के रूप में प्रदर्शित होते हैं। मैं क्या गलत कर रहा हूं?कोड

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 एक "आयु" संपत्ति नहीं है और आप इसका "नाम" सेट नहीं कर रहे हैं।

क्योंकि आप आइटम टेम्पलेट का उपयोग कर रहे हैं, पेड़ पर TreeViewItems जोड़ने की कोई आवश्यकता नहीं है। इसके बजाय, अपने व्यक्ति उदाहरणों सीधे जोड़ें:

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

या, एक बेहतर समाधान, आप अपने "व्यक्ति" वस्तु में पदानुक्रम अवधारणा लागू और TreeView पदानुक्रम परिभाषित करने के लिए एक 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> 

कोड:

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

यह एक अधिक "डेटा" उन्मुख तरीका है अपने पदानुक्रम प्रदर्शित करने के लिए और एक बेहतर दृष्टिकोण IMHO।

+0

आपके दोनों समाधान काम करते हैं। आपको वापस आने के लिए बहुत लंबा समय लगता है। मैं अंत में एक पेड़ का उपयोग नहीं कर पाया, इसके बजाय एक कस्टम पदानुक्रमित सूची बॉक्स लागू किया। –

+1

मैट के लिए हुरेय! बस मुझे क्या चाहिए (दूसरा समाधान) –

0

यदि आप अपने डेटा टेम्पलेट को TreeView से बाहर खींचते हैं और इसे विंडो में डालते हैं तो यह काम करेगा। स्रोत। इस तरह:

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

व्यक्ति के सामने सही नामस्थान जोड़ने के लिए मत भूलना।