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();
      }
  }
}
相关推荐
码观天工7 分钟前
.NET 原生驾驭 AI 新基建实战系列(五):Milvus ── 大规模 AI 应用的向量数据库首选
c#·.net·milvus·向量数据库·高性能
猫猫头有亿点炸29 分钟前
C语言大写转小写2.0
c语言·开发语言
A达峰绮38 分钟前
设计一个新能源汽车控制系统开发框架,并提供一个符合ISO 26262标准的模块化设计方案。
大数据·开发语言·经验分享·新能源汽车
BS_Li1 小时前
C++类和对象(上)
开发语言·c++·类和对象
XiaoyuEr_66881 小时前
C#中属性和字段的区别
开发语言·c#
火星papa1 小时前
C# 利用log4net 工作台打印和保存到文件
c#
ghost1431 小时前
C#学习第19天:多线程
开发语言·学习·c#
钢铁男儿1 小时前
C# 类的基本概念(声明类)
c#
Y1nhl1 小时前
力扣hot100_子串_python版本
开发语言·python·算法·leetcode·职场和发展
李宥小哥1 小时前
Redis03-基础-C#客户端
开发语言·缓存·中间件·c#