You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 18:16:36