博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF MVVM实现TreeView
阅读量:5836 次
发布时间:2019-06-18

本文共 6751 字,大约阅读时间需要 22 分钟。

今天有点时间,做个小例子WPF MVVM 实现TreeView 只是一个思路大家可以自由扩展

文章最后给出了源码下载地址

图1   图2    

模版加上了一个checkbox,选中父类的checkbox 所有的子类也相就选中。

如果子类没有全部父类的checkbox不会选中

用vmmm我们要先实现INotifyPropertyChanged

///     ///     ///     public class NotifyPropertyBase : INotifyPropertyChanged    {        #region INotifyPropertyChanged        public void OnPropertyChanged(string propertyName)        {            if (PropertyChanged != null)            {                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));            }        }        public event PropertyChangedEventHandler PropertyChanged;        #endregion    }

为了避免硬编码错误我写一个扩展方法

///     /// 扩展方法    /// 避免硬编码问题    ///     public static class NotifyPropertyBaseEx    {        public static void SetProperty
(this T tvm, Expression
> expre) where T : NotifyPropertyBase, new() { string _pro = CommonFun.GetPropertyName(expre); tvm.OnPropertyChanged(_pro); } } #endregion public class CommonFun { ///
/// 返回属性名 /// ///
///
///
///
public static string GetPropertyName
(Expression
> expr) { string _propertyName = ""; if (expr.Body is MemberExpression) { _propertyName = (expr.Body as MemberExpression).Member.Name; } else if (expr.Body is UnaryExpression) { _propertyName = ((expr.Body as UnaryExpression).Operand as MemberExpression).Member.Name; } return _propertyName; } }

下面我们就来实现treeveivew的绑定类

///     /// 因为用到泛型了不能写成abstract 类    ///     ///     public  class MyTree : NotifyPropertyBase    {         #region 父        public MyTree Parent        {            get;            set;        }        #endregion        #region 子        public List
Children { get; set; } #endregion #region 节点的名字 public string Name { get; set; } #endregion #region Constructors public MyTree(string name) { this.Name=name; this.Children=new List
(); } public MyTree() { } public #endregion #region CheckBox是否选中 bool? _isChecked; public bool? IsChecked { get { return _isChecked; } set { SetIsChecked(value, true, true); } } private void SetIsChecked(bool? value, bool checkedChildren, bool checkedParent) { if (_isChecked == value) return; _isChecked = value; //选中和取消子类 if (checkedChildren && value.HasValue && Children != null) Children.ForEach(ch => ch.SetIsChecked(value, true, false)); //选中和取消父类 if (checkedParent && this.Parent != null) this.Parent.CheckParentCheckState(); //通知更改 this.SetProperty(x => x.IsChecked); } ///
/// 检查父类是否选 中 /// 如果父类的子类中有一个和第一个子类的状态不一样父类ischecked为null /// private void CheckParentCheckState() { bool? _currentState = this.IsChecked; bool? _firstState = null; for (int i = 0; i < this.Children.Count(); i++) { bool? childrenState = this.Children[i].IsChecked; if (i == 0) { _firstState = childrenState; } else if (_firstState != childrenState) { _firstState = null; } } if (_firstState != null) _currentState = _firstState; SetIsChecked(_firstState, false, true); } #endregion #region 选中的行 IsSelected bool _isSelected; public bool IsSelected { get { return _isSelected; } set { _isSelected = value; this.SetProperty(x => x.IsChecked); if (_isSelected) { SelectedTreeItem = this; MessageBox.Show("选中的是" + SelectedTreeItem.Name); } else SelectedTreeItem = null; } } #endregion #region 选中的数据 public MyTree SelectedTreeItem { get; set; } #endregion #region 创建树 public void CreateTreeWithChildre( MyTree children,bool? isChecked) { this.Children.Add(children); children.Parent = this; children.IsChecked = isChecked; } #endregion }

 

我们再下面实现ViewModel

public class TreeViewModel:NotifyPropertyBase    {        public List
MyTrees { get; set; } public TreeViewModel() { MyTrees = new List
(); MyTrees.Add(MyCreateTree()); } ///
/// 创建树 /// ///
public MyTree MyCreateTree() { MyTree _myT = new MyTree("中国"); #region 北京 MyTree _myBJ = new MyTree("北京"); _myT.CreateTreeWithChildre(_myBJ, false); MyTree _HD = new MyTree("海淀区"); MyTree _CY = new MyTree("朝阳区"); MyTree _FT = new MyTree("丰台区"); MyTree _DC = new MyTree("东城区"); _myBJ.CreateTreeWithChildre(_HD, false); _HD.CreateTreeWithChildre(new MyTree("某某1"), false); _HD.CreateTreeWithChildre(new MyTree("某某2"), true); _myBJ.CreateTreeWithChildre(_CY, false); _myBJ.CreateTreeWithChildre(_FT, false); _myBJ.CreateTreeWithChildre(_DC, false); #endregion #region 河北 MyTree _myHB = new MyTree("河北"); _myT.CreateTreeWithChildre(_myHB, false); MyTree _mySJZ = new MyTree("石家庄"); MyTree _mySD = new MyTree("山东"); MyTree _myTS = new MyTree("唐山"); _myHB.CreateTreeWithChildre(_mySJZ, true); _myHB.CreateTreeWithChildre(_mySD, false); _myHB.CreateTreeWithChildre(_myTS, false); #endregion return _myT; } }

  

我们再实现一个TreeView的模版

 

 

 源码地址:

 

 

转载地址:http://omccx.baihongyu.com/

你可能感兴趣的文章
NYOJ311 完全背包
查看>>
codevs——2822 爱在心中
查看>>
Python基础班---第一部分(基础)---Python基础知识---认识Python
查看>>
JAVA MAC 配置
查看>>
1134 最长上升子序列 (序列型 DP)
查看>>
js冒泡排序
查看>>
第一次作业 4班卢炳武
查看>>
const int * 与 int *const
查看>>
抽象类的调用
查看>>
使用硬盘,安装双系统,Win7+CentOS
查看>>
Javascript学习总结
查看>>
JS 操作Excel格式
查看>>
php 用正则替换中文字符一系列问题解决
查看>>
ActiveMQ应用笔记一:基本概念&安装
查看>>
SAE+Java+jetty
查看>>
大话数据结构之四(串)
查看>>
加热炉简是新来的整个系统的板
查看>>
Mockito使用注意事项
查看>>
[LeetCode] Palindrome Linked List 回文链表
查看>>
UVA - 825Walking on the Safe Side(dp)
查看>>