PowerShell+WPF TreeView层级复选框:父节点选中自动选子节点
实现TreeView父节点选中时自动选中所有子节点
要实现父节点选中时自动选中所有子节点,核心是在Node类的IsChecked属性变更时,递归同步所有子节点的选中状态。同时需要让Node类实现INotifyPropertyChanged接口,确保属性变更能同步到UI。
以下是修改后的完整代码:
[xml]$xaml = @" <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="My TreeView" Height="300" Width="300"> <Grid> <TreeView Name="MyTreeView" Margin="10"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Children}"> <StackPanel Orientation="Horizontal"> <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" VerticalAlignment="Center"/> <TextBlock Text="{Binding Name}" Margin="5,0,0,0"/> </StackPanel> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> </Grid> </Window> "@ $reader=(New-Object System.Xml.XmlNodeReader $xaml) $window=[Windows.Markup.XamlReader]::Load( $reader ) # 定义实现了INotifyPropertyChanged的Node类 class Node : System.ComponentModel.INotifyPropertyChanged { [string]$Name [System.Collections.ObjectModel.ObservableCollection[Node]]$Children [bool]$_isChecked [bool] get_IsChecked() { return $this._isChecked } void set_IsChecked([bool]$value) { if ($this._isChecked -ne $value) { $this._isChecked = $value # 递归设置所有子节点的IsChecked状态 foreach ($child in $this.Children) { $child.IsChecked = $value } $this.OnPropertyChanged("IsChecked") } } # 实现INotifyPropertyChanged接口的事件和方法 event System.ComponentModel.PropertyChangedEventHandler PropertyChanged void OnPropertyChanged([string]$propertyName) { $this.PropertyChanged.Invoke($this, [System.ComponentModel.PropertyChangedEventArgs]::new($propertyName)) } } # 填充示例数据 $root = New-Object Node $root.Name = "Root" $root.Children = New-Object System.Collections.ObjectModel.ObservableCollection[Node] $child1 = New-Object Node $child1.Name = "Child 1" $child1.Children = New-Object System.Collections.ObjectModel.ObservableCollection[Node] # 给Child1添加子节点,测试递归效果 $grandchild1 = New-Object Node $grandchild1.Name = "Grandchild 1-1" $child1.Children.Add($grandchild1) $child2 = New-Object Node $child2.Name = "Child 2" $child2.Children = New-Object System.Collections.ObjectModel.ObservableCollection[Node] $root.Children.Add($child1) $root.Children.Add($child2) $treeview = $window.FindName("MyTreeView") $treeview.ItemsSource = @($root) $window.ShowDialog() | Out-Null
关键修改说明:
- 实现INotifyPropertyChanged接口:确保
IsChecked属性变更时,UI能及时更新状态。 - 重构IsChecked属性:将原来的自动属性改为带getter和setter的属性,在setter中判断值是否变化,若变化则递归遍历所有子节点,同步设置它们的
IsChecked值,最后触发PropertyChanged事件通知UI。 - 添加嵌套子节点测试:示例中给Child1添加了孙节点,验证递归选中的效果。
内容的提问来源于stack exchange,提问作者Rafał Łątka
相关产品推荐
相关产品推荐

