我正在尝试使用MVVM在WPF项目中创建动态生成的TreeView。我已经创建了它将绑定到的HierarchicalDataTemplate和CheckableItem模型。我在ViewModel上有一个CheckableItem类型属性,该属性在构造ViewModel时填充。然后,我让XAML使用该模板创建TreeView,但没有显示任何内容。我需要TreeView包含Checkboxes,如果我的上层复选框被选中,则它应该检查所有下层的复选框。它应该看起来像这样:
我不确定是什么原因导致它无法显示。
ChekableItem类:
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的Children属性,如下所示:
<TreeView ItemsSource="{Binding MiscellaneousImports.Children, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="10" Height="450"/>