需求背景:

当我们用到权限菜单栏时权限菜单栏属于递归效果,我们需要用到TreeView+CheckBox进行组合复选开发时,我们需要解决此类问题时怎么办,那么就引出今天的小笔记内容

实现方式:

下载MVVM框架以及Newtonsoft,这时候可能大家会觉得奇怪,为什么还会用到Json,大家直接看代码,我每一步骤都很详细,代码可直接粘贴,让大家爽一爽

1、创建模型 CheckModel

 1 /// <summary>
2 /// 模型可进行序列化
3 /// </summary>
4 [Serializable]
5 public class CheckModel : BindableBase
6 {
7 public CheckModel()
8 {
9
10 }
11 private bool? _IsSelected=false;
12 public bool? IsSelected
13 {
14 get { return _IsSelected; }
15 set {
16 if (SetProperty(ref _IsSelected, value))
17 {
18 SelectCheck(value, true, true);
19 }
20 }
21 }
22 /// <summary>
23 /// 设置全选状态
24 /// </summary>
25 /// <param name="value"></param>
26 /// <param name="checkedChildren"></param>
27 /// <param name="checkedParent"></param>
28 private void SelectCheck(bool? value, bool checkedChildren, bool checkedParent)
29 {
30 if (checkedChildren && value.HasValue && ChildList != null)
31 foreach (var item in ChildList)
32 {
33 item.SelectCheck(value, true, false);
34 }
35 if (checkedParent && this.Parent != null)//父类模型不为空就进行状态修改
36 this.Parent.CheckParentCheckState();
37 IsSelected = value;
38 }
39 /// <summary>
40 /// 设置父类选中状态
41 /// </summary>
42 private void CheckParentCheckState()
43 {
44 bool? _currentState = this._IsSelected;//临时存储当前选中状态
45 bool? _firstState = null;//刚开始预设为选中状态为空
46
47 for (int i = 0; i < this.ChildList.Count(); i++)
48 {
49 bool? childrenState = this.ChildList[i].IsSelected;//抓起子集合选中状态
50 if (i == 0)//如果为第一次循环,将子集选中状态赋给预设状态
51 {
52 _firstState = childrenState;
53 }
54 else if (_firstState != childrenState)//如果不是第一次循环将预设状态,也就是将父类选中站台标记为空(空代表子集又被选中)
55 {
56 _firstState = null;
57 }
58 }
59 if (_firstState != null) _currentState = _firstState;//如果预设的状态不为空,将预设状态给临时存储当前选中状态
60 SelectCheck(_firstState, false, true);//开始设置选中状态
61 }
62
63 private string _Title;
64 public string Title
65 {
66 get { return _Title; }
67 set { SetProperty(ref _Title, value); }
68 }
69 /// <summary>
70 /// 这一点很关键,解决Json序列化循环依赖问题
71 /// </summary>
72 [JsonIgnore]
73 private CheckModel _Parent;
74 [JsonIgnore]
75 public CheckModel Parent
76 {
77 get { return _Parent; }
78 set { SetProperty(ref _Parent, value); }
79 }
80 private ObservableCollection<CheckModel> _ChildList=new ObservableCollection<CheckModel>();
81 public ObservableCollection<CheckModel> ChildList
82 {
83 get { return _ChildList; }
84 set { SetProperty(ref _ChildList, value); }
85 }
86 }

2、创建ViewModel

 1 public class MainWindowViewModel : BindableBase
2 {
3 public MainWindowViewModel()
4 {
5 CheckModel model = new CheckModel();
6 model.Title = "目录";
7 model.ChildList = new ObservableCollection<CheckModel>();
8 ListData.Add(model);
9 CheckModel chmodel = new CheckModel();
10 chmodel.Title = "目录1";
11 chmodel.Parent = model;
12 CheckModel chmodel_1 = new CheckModel();
13 chmodel_1.Title = "目录1-1";
14 chmodel_1.Parent = chmodel;
15 chmodel.ChildList.Add(chmodel_1);
16 model.ChildList.Add(chmodel);
17 CheckModel chmodel2 = new CheckModel();
18 chmodel2.Title = "目录2";
19 chmodel2.Parent = model;
20 model.ChildList.Add(chmodel2);
21 }
22 private ObservableCollection<CheckModel> _ListData = new ObservableCollection<CheckModel>()
23 {
24
25 };
26 public ObservableCollection<CheckModel> ListData
27 {
28 get { return _ListData; }
29 set { SetProperty(ref _ListData, value); }
30 }
31 private ObservableCollection<CheckModel> _CheckListData = new ObservableCollection<CheckModel>();
32 public ObservableCollection<CheckModel> CheckListData
33 {
34 get { return _CheckListData; }
35 set { SetProperty(ref _CheckListData, value); }
36 }
37 private DelegateCommand _CheckedCommand;
38 public DelegateCommand CheckedCommand =>
39 _CheckedCommand ?? (_CheckedCommand = new DelegateCommand(ExecuteCheckedCommand));
40
41 void ExecuteCheckedCommand()
42 {
43 CheckListData.Clear();
44 #region 这一点很重要,用过Json解决集合地址引用问题,如果直接进行原有集合抓取选中状态,那么你进行递归筛查时涉及到数据地址引用问题,造成源数据被破环问题,利用Json序列化字符串就可以完美就解决地址引用问题
45 string datas = Newtonsoft.Json.JsonConvert.SerializeObject(ListData.ToList());
46 ObservableCollection<CheckModel> list = Newtonsoft.Json.JsonConvert.DeserializeObject<ObservableCollection<CheckModel>>(datas);
47 CheckListData = new ObservableCollection<CheckModel>(GetCheckedItems(list));
48 #endregion
49 //#region 还原上面描述场景
50 //CheckListData = new ObservableCollection<CheckModel>(GetCheckedItems(ListData));
51 //#endregion
52 }
53 /// <summary>
54 /// 获取选中项
55 /// </summary>
56 /// <param name="tree">需要递归的集合</param>
57 private ObservableCollection<CheckModel> GetCheckedItems(ObservableCollection<CheckModel> tree)
58 {
59 //用于存储抓取的选中临时数据
60 ObservableCollection<CheckModel> list = new ObservableCollection<CheckModel>();
61 if (tree.ToList().Count > 0)
62 {
63 foreach (var item in tree)
64 {
65 //检测选中状态
66 if (item.IsSelected != false) {
67 //防呆,检测集合空值。若为空值 直接进行添加当前对象
68 if (item.ChildList!=null)
69 {
70 //很重要->>>递归抓取下一层集合数据赋予当前模型集合
71 item.ChildList = GetCheckedItems(item.ChildList);
72 //填充当前抓取的对象
73 list.Add(item);
74 }
75 else {
76 /// 填充当前抓取的对象
77 list.Add(item);
78 }
79 }
80 }
81 }
82 return list;
83 }
84 }

备注:

  原创文章禁止转载 2022-02-18

WPF之复选MVVM TreeView(TreeView+CheckBox)的更多相关文章

  1. 关于复选框input[type=checkbox]

    关于复选框input[type=checkbox],其实在前面的文章中说过一次,当时主要关注点在设置复选框的状态,利用prop实现,今天继续关注一下复选框. 自己在项目中,遇到一个全选/全不选的需求, ...

  2. js做全选,用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false

    用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false,当所有checkbox都被选中时,全选按钮也被选中. 详解: 有两种 ...

  3. WPF:带复选框CheckBox的树TreeView

    最近要用WPF写一个树,同事给了我一个Demo(不知道是从哪里找来的),我基本上就是参照了这个Demo. 先放一下效果图(3棵树): 这个树索要满足的条件是: 父节点.Checked=true时,子节 ...

  4. 实现带复选框的TreeView控件

    实现效果: 知识运用: TreeView控件的CheckView属性 //是否在树形视图控件中显示复选框 public bool CheckBoxs{ get;ser } 实现代码: TreeView ...

  5. 表单复选框input[type="checkbox"]

    <!DOCTYPE html> <html lang="zh"> <head> <title></title> < ...

  6. pentaho cde 自定义复选下拉框 checkbox select

    pentaho  自带的component 虽多,但是当用户需要在一个表格中查看多个组别的数据时,pentaho自带的单选框就不能实现了,所以复选下拉框势在必行,实现效果如下: 实现原理是借用了jqu ...

  7. 复选框(checkbox)、单选框(radiobox)的使用

    复选框(checkbox).单选框(radiobox)的使用 复选框: HTML: // 复选框 <input type="checkbox" name="chec ...

  8. Selenium2+python自动化19-单选框和复选框(radiobox、checkbox)

    本篇主要介绍单选框和复选框的操作 一.认识单选框和复选框 1.先认清楚单选框和复选框长什么样 2.各位小伙伴看清楚哦,上面的单选框是圆的:下图复选框是方的,这个是业界的标准,要是开发小伙伴把图标弄错了 ...

  9. firefox中 checkbox属性checked="checked"已有,但复选框却不显示打钩的原因

    最近在调试复选框的应用,在ie没有问题,考虑到兼容性,试试了firefox,遇到了问题. 复选框绑定了click事件,点一次选中,再点击取消选中,依次类推.这个功能在ie中没问题,但是在firefox ...

随机推荐

  1. Hadoop的Shuffle阶段

    原文: https://www.toutiao.com/i6764683672772674062/ 在进入Map之前,首先会将数据从HDFS中读取,进行处理,按照字节偏移量这种之前说的形式处理为K,V ...

  2. BugKu CTF(杂项篇MISC)-贝斯手

    打开是以下内容 先看一下给了哪些提示 1.介绍 没了?不,拉到最底下还有 2.女神剧照 密码我4不会告诉你的,除非你知道我的女神是哪一年出生的(细品) 大致已经明白了,四位数密码,出生年份 文件是以下 ...

  3. TextBox,RichTextBox设置行高

    /// <summary> /// 设置行距 /// </summary> /// <param name="ctl">控件</param ...

  4. nacos集群开箱搭建

    记录/朱季谦 nacos是一款易于构建云原生应用的动态服务发现.配置管理和服务管理平台,简单而言,它可以实现类似zookeeper做注册中心的功能,也就是可以在springcloud领域替代Eurek ...

  5. 多线程-停止线程方式-Interrupt

    1 package multithread4; 2 /* 3 * 停止线程: 4 * 1,stop方法. 5 * 6 * 2,run方法结束. 7 * 8 * 怎么控制线程的任务结束呢? 9 * 任务 ...

  6. Git算不算程序员的必备技能?

    作者:慕课网链接:https://www.zhihu.com/question/41667536/answer/486640083来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  7. 009 Linux 文件大小统计与排序( du于df和sort)

    @ 目录 01 du 与 df 作用与区别? du(disk usage) df(disk free) 02 du 常用命令示例 03 sort 常用参数 04 常用组合 du + sort + he ...

  8. Execution default-resources of goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources failed.

    说明 今天发现这个错误,然后整体检查了一下代码,没有发现任何错误,最后没法只有来一步一步排查. 解决 确定pom文件是否有问题 如上图,有红色波浪线,代表错误,请检查并解决,还有版本是否冲突,最好把不 ...

  9. php curl发送post get请求

    POST: function curl_post_https($url, $data, $header){ // 模拟提交数据函数 $curl = curl_init(); // 启动一个CURL会话 ...

  10. 异步回调实现- Guava Retryer

    为什么要使用重试利器Retryer 在实际开发中我们经常会遇到需要轮询查询一个接果,实现轮询的方式有很多种,我们经常要写许多代码,有时还会怕写出的代码有bug,如果已经有轮子了,我们就没必要重复造轮子 ...