使树视图工作的代码缺少什么?

What is missing from the code to make the treeview work?

下面的问题让我很抓狂,这两天下午都在努力解决这个问题,所以我真的很努力地研究它。

我的问题是,当我对树视图使用数据绑定时,它似乎不起作用。我可能遗漏了一些东西,我想请你帮忙找到它。

对于 WPF XAML 我正在使用以下代码:

<Window x:Class="MesDiag2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:MesDiag2"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

<Window.Resources>
    <HierarchicalDataTemplate ItemsSource="{Binding Materials}" DataType="{x:Type local:ProductNode}">
        <Label Content="{Binding Product.LotName}"/>
    </HierarchicalDataTemplate>
</Window.Resources>

<Grid>

    <TreeView ItemsSource="{Binding Root}">

    </TreeView>


</Grid>

我的 class 如下,请注意,这只是我做的一个 "test" 项目,以查看问题出在哪里。我试图让一切尽可能简单。每个 class 的 INotifyPropertyChanged 只是一次绝望的尝试,看看它是否修复了它:

using System.ComponentModel;

namespace MesDiag2
{
    public class Product : INotifyPropertyChanged
    {
        string lotName;
        public string LotName
        {
            get { return lotName; }
            set
            {
                lotName = value;
                NotifyPropertyChanged("LotName");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

TreeViewItem 的上下文应该如下class:

using System.Collections.Generic;
using System.ComponentModel;

namespace MesDiag2
{
    public class ProductNode : INotifyPropertyChanged
    {
        Product product;
        List<Product> materials;

        public ProductNode(Product product)
        {
            Materials = new List<Product>();
            Product = product;
        }

        public Product Product
        {
            get { return product; }
            set
            {
                product = value;
                NotifyPropertyChanged("Product");
            }
        }

        public List<Product> Materials
        {
            get { return materials; }
            set
            {
                materials = value;
                NotifyPropertyChanged("Materials");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

我的视图模型:

using System.ComponentModel;

namespace MesDiag2
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ProductNode Root { get; set; }
        public string Test { get; set; }

        public ViewModel()
        {
            Root = new ProductNode(new Product { LotName = "Test" });
            Test = "Hello";
        }



        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

最后是我主窗口的内容 class:

使用 System.Windows;

namespace MesDiag2
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new ViewModel();
        }
    }
}

我完成 WPF 已经有一段时间了,但我想你想做这样的事情:

<TreeView ItemsSource="{Binding Root.Materials}">
    <HierarchicalDataTemplate>
        <Label Content="{Binding LotName}"/>
    </HierarchicalDataTemplate>
</TreeView>

我还会:

 List<Product> materials;

这个:

 ObservableCollection<Product> materials

https://docs.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=netframework-4.8