绑定到 ObservableCollection 时,如何让子树节点出现在 WPF TreeView 中?

发布于 2024-08-22 19:28:06 字数 3603 浏览 6 评论 0原文

我必须在以下代码中更改什么才能使“子部分”节点显示为第一部分和<强>第二部分:

以下代码给了我一个XamlParseException。

XAML:

<Window x:Class="TestTr32322.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestTr32322"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <HierarchicalDataTemplate x:Key="sectionTemplate" 
            ItemsSource="{Binding ChildSections}"
            DataType="{x:Type local:Section}">
            <TextBlock Text="{Binding Title}" />
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <TreeView ItemsSource="{Binding Sections}" 
                  ItemTemplate="{StaticResource sectionTemplate}">
        </TreeView>
    </Grid>
</Window>

代码隐藏:

using System.Windows;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace TestTr32322
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {
        #region ViewModelProperty: Sections
        private ObservableCollection<Section> _sections = new ObservableCollection<Section>();
        public ObservableCollection<Section> Sections
        {
            get
            {
                return _sections;
            }

            set
            {
                _sections = value;
                OnPropertyChanged("Sections");
            }
        }
        #endregion

        public Window1()
        {
            InitializeComponent();
            DataContext = this;

            Sections = Section.GetSections();
        }

        #region INotifiedProperty Block
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

    }

    public class Section
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public ObservableCollection<Section> ChildSections { get; set; }

        public static ObservableCollection<Section> GetSections()
        {
            ObservableCollection<Section> sections = new ObservableCollection<Section>();

            {
                Section section = new Section();
                section.Title = "First Section";
                section.ChildSections.Add(new Section
                {
                    Title = "A Child Section",
                    Description = "this is the description",
                    ChildSections = new ObservableCollection<Section>()
                });
                sections.Add(section);
            }

            {
                Section section = new Section();
                section.Title = "Second Section";
                section.ChildSections.Add(new Section
                {
                    Title = "A Child  Section",
                    Description = "this is the description",
                    ChildSections = new ObservableCollection<Section>()
                });
                sections.Add(section);
            }

            return sections;
        }
    }

}

What do I have to change in the following code to make the "A Child Section" node appear as a child of the First Section and Second Section:

The following code gives me a XamlParseException.

XAML:

<Window x:Class="TestTr32322.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestTr32322"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <HierarchicalDataTemplate x:Key="sectionTemplate" 
            ItemsSource="{Binding ChildSections}"
            DataType="{x:Type local:Section}">
            <TextBlock Text="{Binding Title}" />
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <TreeView ItemsSource="{Binding Sections}" 
                  ItemTemplate="{StaticResource sectionTemplate}">
        </TreeView>
    </Grid>
</Window>

Code Behind:

using System.Windows;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace TestTr32322
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {
        #region ViewModelProperty: Sections
        private ObservableCollection<Section> _sections = new ObservableCollection<Section>();
        public ObservableCollection<Section> Sections
        {
            get
            {
                return _sections;
            }

            set
            {
                _sections = value;
                OnPropertyChanged("Sections");
            }
        }
        #endregion

        public Window1()
        {
            InitializeComponent();
            DataContext = this;

            Sections = Section.GetSections();
        }

        #region INotifiedProperty Block
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

    }

    public class Section
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public ObservableCollection<Section> ChildSections { get; set; }

        public static ObservableCollection<Section> GetSections()
        {
            ObservableCollection<Section> sections = new ObservableCollection<Section>();

            {
                Section section = new Section();
                section.Title = "First Section";
                section.ChildSections.Add(new Section
                {
                    Title = "A Child Section",
                    Description = "this is the description",
                    ChildSections = new ObservableCollection<Section>()
                });
                sections.Add(section);
            }

            {
                Section section = new Section();
                section.Title = "Second Section";
                section.ChildSections.Add(new Section
                {
                    Title = "A Child  Section",
                    Description = "this is the description",
                    ChildSections = new ObservableCollection<Section>()
                });
                sections.Add(section);
            }

            return sections;
        }
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜心 2024-08-29 19:28:06

您似乎需要 HierarchicalDataTemplate。他们在文章中有一个例子......

It looks like you need HierarchicalDataTemplate. They have an example in the article...

别挽留 2024-08-29 19:28:06

看看这个问题 和接受的答案。它也应该为您指明正确的方向。

基本思想是使用 ItemsSource 属性定义 HierarchicalDataTemplates 并使它们按类型匹配。

对于您的情况:

<HierarchicalDataTemplate DataType="{x:Type local:Section}" 
                          ItemsSource="{Binding ChildSection}">
    <TextBlock Text="{Binding Path=Title}" />
</HierarchicalDataTemplate>

编辑
在代码中,您应该在向其添加值之前创建一个新集合:

// The new was missing and resulted in the end in your XAML Parse Exception
section.ChildSections = new ObservableCollection<Section>();
section.ChildSections.Add( /*... */);

Have a look at this question and the accepted answer. It should point you into the right direction, too.

The basic idea is to define HierarchicalDataTemplates with an ItemsSource property and make them match by type.

In your case:

<HierarchicalDataTemplate DataType="{x:Type local:Section}" 
                          ItemsSource="{Binding ChildSection}">
    <TextBlock Text="{Binding Path=Title}" />
</HierarchicalDataTemplate>

Edit:
In your code you should create a new collection before adding a value to it:

// The new was missing and resulted in the end in your XAML Parse Exception
section.ChildSections = new ObservableCollection<Section>();
section.ChildSections.Add( /*... */);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文