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"/>
我正在尝试使用 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"/>