treeview形式的checkbox(wpf、c#)

如何实现treeview形式的checkbox,并且父节点和子节点的选中状态可相互影响。示例图:

代码如下:

wpf代码:treeview绑定的数据是PermissionDataCollection。

csharp 复制代码
<TreeView ItemsSource="{Binding PermissionDataCollection}">
	<TreeView.ItemTemplate>
		<HierarchicalDataTemplate ItemsSource="{Binding Children}">
			<StackPanel Orientation="Horizontal" >
				<CheckBox IsChecked="{Binding IsChecked}"/>
				<TextBlock Text="{Binding Name}"/>
			 </StackPanel>
		</HierarchicalDataTemplate>
	</TreeView.ItemTemplate>
</TreeView>

后端数据来源:PermissionDataCollection的声明及定义:

csharp 复制代码
public ObservableCollection<TreeViewItemModel> PermissionDataCollection { get; set; }
csharp 复制代码
PermissionDataCollection = new ObservableCollection<TreeViewItemModel>();

// 添加根节点
var rootNode = new TreeViewItemModel { Name = "所有权限", IsChecked = false, Children = new ObservableCollection<TreeViewItemModel>() };
PermissionDataCollection0.Add(rootNode);

// 添加子节点
var childNode1 = new TreeViewItemModel { Name = "系统设置", IsChecked = false, Children = new ObservableCollection<TreeViewItemModel>(), Parent = rootNode };
var childNode2 = new TreeViewItemModel { Name = "日志管理", IsChecked = true, Children = new ObservableCollection<TreeViewItemModel>(), Parent = rootNode };
rootNode.Children.Add(childNode1);
rootNode.Children.Add(childNode2);

// 添加孙子节点
var grandChildNode1 = new TreeViewItemModel { Name = "相机设置", IsChecked = true, Children = new ObservableCollection<TreeViewItemModel>(), Parent = childNode1 };
var grandChildNode2 = new TreeViewItemModel { Name = "参数设置", IsChecked = false, Children = new ObservableCollection<TreeViewItemModel>(), Parent = childNode1};
childNode1.Children.Add(grandChildNode1);
childNode1.Children.Add(grandChildNode2);

TreeViewItemModel的定义:(也就是定义treeview形式的checkbox)

csharp 复制代码
public class TreeViewItemModel : INotifyPropertyChanged
{
  private bool _isChecked;
  private bool _isUpdatingChildren;

  public string Name { get; set; }

  public bool IsChecked
  {
      get { return _isChecked; }
      set
      {
          if (_isChecked != value)
          {
              _isChecked = value;
              OnPropertyChanged(nameof(IsChecked));

              if (!_isUpdatingChildren && Children != null)
              {
                  _isUpdatingChildren = true;

                  // 递归设置子节点的勾选状态
                  foreach (var child in Children)
                  {
                      child.IsChecked = value;
                  }

                  _isUpdatingChildren = false;
              }

              // 更新父节点的勾选状态
              if (Parent != null)
              {
                  UpdateParentCheckedState();
              }
          }
      }
  }

  public ObservableCollection<TreeViewItemModel> Children { get; set; }

  public TreeViewItemModel Parent { get; set; }

  public event PropertyChangedEventHandler PropertyChanged;

  protected virtual void OnPropertyChanged(string propertyName)
  {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }

  public void UpdateParentCheckedState()
  {
      if (Parent != null)
      {
          bool allSiblingsChecked = Parent.Children.All(child => child.IsChecked);
          bool anySiblingChecked = Parent.Children.Any(child => child.IsChecked);

          if (allSiblingsChecked)
          {
              Parent._isChecked = true;
          }
          else if (anySiblingChecked)
          {
              Parent._isChecked = false;
          }
          else
          {
              Parent._isChecked = false;
          }

          Parent.OnPropertyChanged(nameof(IsChecked));
          Parent.UpdateParentCheckedState();
      }
  }
}
相关推荐
波波0075 分钟前
用微软AutoGen+ 通义千问实现 AI 成语接龙
人工智能·microsoft·c#
怪我冷i7 分钟前
在win11进行Rust Web 开发,采用Salvo框架
开发语言·前端·rust
吴声子夜歌8 分钟前
Node.js——os操作系统模块
开发语言·node.js·php
曹牧9 分钟前
Java:驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立连接
java·开发语言·ssl
cch89189 分钟前
PHP vs C++:10倍性能差距的编程语言对决
android·java·开发语言
司马万9 分钟前
RUST基础1----数据类型
开发语言·算法·rust
cnnews10 分钟前
Termux中安装python包
android·linux·开发语言·python·安卓·termux
房开民8 小时前
c++总结
java·开发语言·c++
毕设源码-赖学姐8 小时前
【开题答辩全过程】以 基于Java的医院器材管理系统的设计与实现为例,包含答辩的问题和答案
java·开发语言
float_com9 小时前
【java常用API】----- Arrays
java·开发语言