代码之家  ›  专栏  ›  技术社区  ›  Wallstreet Programmer

在代码中添加项时对树视图使用项模板

  •  10
  • Wallstreet Programmer  · 技术社区  · 15 年前

    我正在代码隐藏中手动添加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; }
        }
    }
    
    2 回复  |  直到 15 年前
        1
  •  11
  •   Nawed Nabi Zada    7 年前

    您的itemTemplate试图在textBlocks中呈现“name”和“age”属性,但TreeViewItem没有“age”属性,并且您没有设置其“name”。

    因为您使用的是项模板,所以不需要将TreeView项添加到树中。相反,直接添加您的个人实例:

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

    当然,问题是你的底层对象(“人”)没有任何层次结构的概念,所以没有简单的方法将“乔”添加到“萨利”中。有几个更复杂的选项:

    您可以尝试处理treeview.itemcontainerGenerator.statusChanged事件,然后等待生成“sally”项,然后获取该项的句柄并直接添加joe:

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

    或者,更好的解决方案是,您可以将层次结构概念引入到“Person”对象中,并使用HierarchicalDataTemplate定义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>
    

    代码:

    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。

        2
  •  0
  •   Dong    8 年前

    如果您将数据模板从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之前添加正确的命名空间。