WPF之复选MVVM TreeView(TreeView+CheckBox)
需求背景:
当我们用到权限菜单栏时权限菜单栏属于递归效果,我们需要用到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)的更多相关文章
- 关于复选框input[type=checkbox]
关于复选框input[type=checkbox],其实在前面的文章中说过一次,当时主要关注点在设置复选框的状态,利用prop实现,今天继续关注一下复选框. 自己在项目中,遇到一个全选/全不选的需求, ...
- js做全选,用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false
用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false,当所有checkbox都被选中时,全选按钮也被选中. 详解: 有两种 ...
- WPF:带复选框CheckBox的树TreeView
最近要用WPF写一个树,同事给了我一个Demo(不知道是从哪里找来的),我基本上就是参照了这个Demo. 先放一下效果图(3棵树): 这个树索要满足的条件是: 父节点.Checked=true时,子节 ...
- 实现带复选框的TreeView控件
实现效果: 知识运用: TreeView控件的CheckView属性 //是否在树形视图控件中显示复选框 public bool CheckBoxs{ get;ser } 实现代码: TreeView ...
- 表单复选框input[type="checkbox"]
<!DOCTYPE html> <html lang="zh"> <head> <title></title> < ...
- pentaho cde 自定义复选下拉框 checkbox select
pentaho 自带的component 虽多,但是当用户需要在一个表格中查看多个组别的数据时,pentaho自带的单选框就不能实现了,所以复选下拉框势在必行,实现效果如下: 实现原理是借用了jqu ...
- 复选框(checkbox)、单选框(radiobox)的使用
复选框(checkbox).单选框(radiobox)的使用 复选框: HTML: // 复选框 <input type="checkbox" name="chec ...
- Selenium2+python自动化19-单选框和复选框(radiobox、checkbox)
本篇主要介绍单选框和复选框的操作 一.认识单选框和复选框 1.先认清楚单选框和复选框长什么样 2.各位小伙伴看清楚哦,上面的单选框是圆的:下图复选框是方的,这个是业界的标准,要是开发小伙伴把图标弄错了 ...
- firefox中 checkbox属性checked="checked"已有,但复选框却不显示打钩的原因
最近在调试复选框的应用,在ie没有问题,考虑到兼容性,试试了firefox,遇到了问题. 复选框绑定了click事件,点一次选中,再点击取消选中,依次类推.这个功能在ie中没问题,但是在firefox ...
随机推荐
- 周末撸了个Excel框架,现已开源,yyds!!
大家好,我是冰河~~ 不管是传统软件企业还是互联网企业,不管是管理软件还是面向C端的互联网应用.都不可避免的会涉及到报表操作,而对于报表业务来说,一个很重要的功能就是将数据导出到Excel. 如果我们 ...
- NPOI Excel导入Invalid header signature
excel是从网页下载或者其他第三方软件导出的解决方法:使用excel打开,另存为2003版的excel,再导入就好了或者保存为 xlsx
- 【小记录】cv::cuda::Stream中取出cudaStream_t并用于核函数的计算
以下是找到的代码 1 cv::cuda::Stream stream; 2 cudaStream_t s = cv::cuda::StreamAccessor::getStream(stream); ...
- 如何理解python中的cmp_to_key()函数
cmp_to_key() 在functools包里的函数,将老式的比较函数(cmp function)转化为关键字函数(key function). 与接受key function的工具一同使用(如 ...
- golang中的原子操作atomic包
1. 概念 原子操作 atomic 包 加锁操作涉及到内核态的上下文切换,比较耗时,代价高, 针对基本数据类型我们还可以使用原子操作来保证并发的安全, 因为原子操作是go语言提供的方法,我们在用户态就 ...
- gin中映射查询字符串或表单参数
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() { r := gin. ...
- ansible roles实践——安装java
[root@master] /etc/ansible$ cat roles/java/tasks/main.yml ---- name: unzip jdk unarchive: src=jdk-8u ...
- python os模块 文件操作
Python内置的os模块可以通过调用操作系统提供的接口函数来对文件和目录进行操作 os模块的基本功能: >>> import os >>> os.name 'po ...
- Python初学笔记之字符串
一.字符串的定义 字符串是就一堆字符,可以使用""(双引号).''(单引号)来创建. 1 one_str = "定义字符串" 字符串内容中包含引号时,可以使用转 ...
- 开发升讯威在线客服系统启示录:怎样编写堪比 MSDN 的用户手册
本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程. 免费在线使用 & 免费私有化部署:https://kf.shengxunwei.com 文章目 ...