如何正确地将对象绑定到 Treeview

How to Properly Bind Object(s) to a Treeview

我一直在自学 C#,一直想编写一个使用树视图的 WPF 应用程序。不过,我花了很多时间弄清楚如何让数据绑定与它一起工作。

有人可以告诉我哪里出错了吗?在这一点上,我只是想得到一些东西,任何东西都可以在树中显示。我发现的显示如何使用 treeview 的资源让我很困惑。

提前感谢您的宝贵时间

编辑: 感谢您的回复。将 ItemSource = {Cars} 添加到树视图中已经引入了我实例化的两辆车的 Make。我如何着手使汽车可以扩展以显示功能列表?我会尝试自己解决这个问题,但此时任何帮助都将不胜感激,因为我对这个问题感到有点沮丧。

Cars.cs

using System;
using System.Collections.Generic;

namespace TreeViewTest
{
    public class Cars
    {
        public List<Car> CarCollection { get; set; }

    }

    public class Car
    {
        public String Make { get; set; }
        public String Model { get; set; }
        public int Year { get; set; }
        public List<String> Features { get; set; }

    }
}

MainWindowViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace TreeViewTest
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        private List<Car> _Cars;

        public List<Car> Cars
        {
            get { return _Cars; }
            set
            {

                if (_Cars == value)
                {
                    return;
                }   
                _Cars = value;
                NotifyPropertyChanged();
            }
        }

        public Car _Car;
        public Car Car
        {
            get { return _Car; }
            set
            {
                if (_Car == value)
                {
                    return;
                }
                _Car = value;
                NotifyPropertyChanged();

            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Windows;

namespace TreeViewTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        MainWindowViewModel _MainWindowContext = new MainWindowViewModel();

        public MainWindow()
        {


            DataContext = _MainWindowContext;
            List<String> basicFeatures = new List<string>() { "Air Conditioning", "AM/FM Radio"};
            Car Rav4 = new Car() { Make = "Toyota", Model = "Rav4", Year = 2001, Features = basicFeatures};
            Car ModelX = new Car() { Make = "Tesla", Model = "Model X", Year = 2020, Features = basicFeatures};
            List<Car> theseCars = new List<Car>() { Rav4, ModelX };
            _MainWindowContext.Car = Rav4;
            _MainWindowContext.Cars = theseCars;

            InitializeComponent();
        }


    }
}

MainWindow.xaml

<Window x:Class="TreeViewTest.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:TreeViewTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Grid.Column="0">    
            <TreeView Grid.Row="0" Grid.Column="0" Height="150">
                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding CarCollection}" DataType="{x:Type local:Cars}">
                        <StackPanel Orientation="Horizontal">
                            <TreeViewItem Header="{Binding Make}"/>
                        </StackPanel>
                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>
            </TreeView>

        </StackPanel>

    </Grid>
</Window>

添加

ItemsSource="{Binding Cars}"

到 TreeView

编辑

这就是将具有各自特征的汽车作为子节点进行布局的方式。

<TreeView Grid.Row="0" Grid.Column="0" Height="150" ItemsSource="{Binding Cars}">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:Car}" ItemsSource="{Binding Features}">
            <TextBlock Text="{Binding Make}"/>
            <HierarchicalDataTemplate.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding}"/>
                </DataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

您将 Cars 传递给 TreeView 控件本身,因此它有一个项目源。

<TreeView ItemsSource="{Binding Cars}">

然后你通过资源定义模板。在您的情况下,它是 HierarchicalDataTemplate,因为 cars 有另一个级别。

<TreeView.Resources>
    <HierarchicalDataTemplate DataType="{x:Type local:Car}" ItemsSource="{Binding Features}">
    </HierarchicalDataTemplate>
</TreeView.Resources>

重要的是要说明您的 HierarchicalDataTemplate 数据类型是 Car,然后您还必须定义 ItemsSource。 基本上你对 WPF 说的是:每当你遇到一种汽车时,请布置一个层次结构并使用你可以在汽车类型上找到的功能集合。

在此之后您定义实际内容。内容是一个显示 Make 属性 from type Car 的 TextBlock,然后我们定义了 HierarchicalDataTemplate ItemTemplate。所以在这里我们要对 WPF 说,一旦您布置了 Car,请确保您也布置了子节点。在您的案例中没有特定的 属性 绑定,因为它是一个字符串列表。

<TextBlock Text="{Binding Make}"/>
<HierarchicalDataTemplate.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding}"/>
    </DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>