WPF 动态生成的 TreeView 不显示复选框

WPF Dynamically Generated TreeView with Checkboxes Not Displaying

我正在尝试使用 MVVM 在 WPF 项目中创建一个动态生成的 TreeView。我已经创建了一个 HierarchicalDataTemplate 和一个它将绑定到的 CheckableItem 模型。我在构建 ViewModel 时填充的 ViewModel 上有一个 CheckableItem 类型 属性。然后我让 XAML 使用模板创建 TreeView,但没有显示任何内容。我需要 TreeView 包含复选框,如果我选中了更高级别的复选框,它应该检查所有较低级别的复选框。它应该看起来像这样:

我不确定是什么问题导致它不显示。

ChekableItem class:

public class CheckableItem
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string _name;
        public string Name
        {
            get { return _name; }
            set 
            { 
                _name = value;
                OnPropertyChanged("Name");
            }
        }
        public ObservableCollection<CheckableItem> Children { get; set; }
        private Visibility _isChecked;
        public Visibility IsChecked
        {
            get { return _isChecked; }
            set
            {
                _isChecked = value;
                OnPropertyChanged("IsChecked");
                CheckChildren(value);               
            }
        }
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        private void CheckChildren(Visibility parentIsChecked)
        {
            foreach (CheckableItem child in Children)
            {
                child.IsChecked = parentIsChecked;
            }
        }

ViewModel:

    private CheckableItem miscellaneousImports;
    public CheckableItem MiscellaneousImports
    {
        get { return miscellaneousImports; }
        set
        {
            miscellaneousImports = value;
            OnPropertyChanged("MiscellaneousImports");
        }
    }
    private void LoadCheckableItems()
            {
                miscellaneousImports = new CheckableItem()
                {
                    Name = "Miscellaneous Imports"
                };
                miscellaneousImports.Children = new ObservableCollection<CheckableItem>();
                miscellaneousImports.Children.Add(new CheckableItem()
                {
                    Name = "GPO Import"
                });
            }
     protected void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }

查看XAML:

    <Window x:Class="CAVA_IAS.Views.CaImportView"
        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:models="clr-namespace:CAVA_IAS.Models"
        mc:Ignorable="d"
        Title="CaImportView" SizeToContent="WidthAndHeight">
    <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type models:CheckableItem}" ItemsSource="{Binding 
            Children}">
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding IsChecked}"/>
                <TextBlock Text="{Binding Name}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </Window.Resources>

    <StackPanel>
        <Label Content="Miscellaneous Imports" HorizontalAlignment="Center" />
        <ScrollViewer>
            <TreeView ItemsSource="{Binding MiscellaneousImports, Mode=TwoWay, 
                  UpdateSourceTrigger=PropertyChanged}" FontSize="10" Height="450"/>
        </ScrollViewer>
    </StackPanel>

您的问题是 TreeView 的 ItemsSource 需要是某种列表。现在您将它绑定到单个 CheckableItem。

在你的 ViewModel 中,你应该有这样的东西:

private ObservableCollection<CheckableItem> miscellaneousImports;
public ObservableCollection<CheckableItem> MiscellaneousImports
{
    get { return miscellaneousImports; }
    set
    {
        miscellaneousImports = value;
        OnPropertyChanged("MiscellaneousImports");
    }
}

或绑定到 Xaml 中 CheckableItem 的子 属性,像这样:

<TreeView ItemsSource="{Binding MiscellaneousImports.Children, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="10" Height="450"/>