WPF MVVM实现TreeView
今天有点时间,做个小例子WPF MVVM 实现TreeView 只是一个思路大家可以自由扩展
文章最后给出了源码下载地址
图1
图2 
模版加上了一个checkbox,选中父类的checkbox 所有的子类也相就选中。
如果子类没有全部父类的checkbox不会选中
用vmmm我们要先实现INotifyPropertyChanged
/// <summary>
///
/// </summary>
public class NotifyPropertyBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
为了避免硬编码错误我写一个扩展方法
/// <summary>
/// 扩展方法
/// 避免硬编码问题
/// </summary>
public static class NotifyPropertyBaseEx
{
public static void SetProperty<T, U>(this T tvm, Expression<Func<T, U>> expre) where T : NotifyPropertyBase, new()
{
string _pro = CommonFun.GetPropertyName(expre);
tvm.OnPropertyChanged(_pro);
}
}
#endregion public class CommonFun
{
/// <summary>
/// 返回属性名
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <param name="expr"></param>
/// <returns></returns>
public static string GetPropertyName<T, U>(Expression<Func<T, U>> 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的绑定类
/// <summary>
/// 因为用到泛型了不能写成abstract 类
///
/// </summary>
public class MyTree : NotifyPropertyBase
{ #region 父
public MyTree Parent
{
get;
set;
}
#endregion #region 子
public List<MyTree> Children
{
get;
set;
}
#endregion #region 节点的名字
public string Name
{
get;
set;
}
#endregion #region Constructors
public MyTree(string name)
{
this.Name=name;
this.Children=new List<MyTree>();
}
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);
} /// <summary>
/// 检查父类是否选 中
/// 如果父类的子类中有一个和第一个子类的状态不一样父类ischecked为null
/// </summary>
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<MyTree> MyTrees
{
get;
set;
}
public TreeViewModel()
{
MyTrees = new List<MyTree>();
MyTrees.Add(MyCreateTree()); }
/// <summary>
/// 创建树
/// </summary>
/// <returns></returns>
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的模版
<Window x:Class="MyWpfCheckTreeDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:MyWpfCheckTreeDemo.AppViewModel"
Title="MainWindow" Height="" Width="" Loaded="LoadedEvent">
<Window.Resources>
<HierarchicalDataTemplate x:Key="MyTreeItemTemplate" DataType="{x:Type VM:MyTree}" ItemsSource="{Binding Path=Children,Mode=OneWay}">
<StackPanel x:Name="My_SP" Orientation="Horizontal" Margin="">
<CheckBox IsChecked="{Binding Path=IsChecked}" >
</CheckBox>
<ContentPresenter Content="{Binding Path=Name,Mode=OneTime}" Margin="2,0"/>
</StackPanel>
</HierarchicalDataTemplate>
<Style x:Key="TreeViewItemStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True" />
<Setter Property="IsSelected" Value="{Binding Path=IsSelected,Mode=TwoWay}"/>
</Style>
</Window.Resources>
<Grid>
<DockPanel> <TreeView x:Name="tv" ItemsSource="{Binding MyTrees}"
ItemContainerStyle="{StaticResource TreeViewItemStyle}"
ItemTemplate="{StaticResource MyTreeItemTemplate}"
></TreeView>
</DockPanel> </Grid>
</Window>
WPF MVVM实现TreeView的更多相关文章
- WPF - MVVM 之TreeView
在项目中使用OnPropertyChanged方法,最简单的实例: private event PropertyChangedEventHandler PropertyChanged; protect ...
- WPF MVVM 验证
WPF MVVM(Caliburn.Micro) 数据验证 书接前文 前文中仅是WPF验证中的一种,我们暂且称之为View端的验证(因为其验证规是写在Xaml文件中的). 还有一种我们称之为Model ...
- WPF MVVM初体验
首先MVVM设计模式的结构, Views: 由Window/Page/UserControl等构成,通过DataBinding与ViewModels建立关联: ViewModels:由一组命令,可以绑 ...
- WPF/MVVM 快速开始指南(译)(转)
WPF/MVVM 快速开始指南(译) 本篇文章是Barry Lapthorn创作的,感觉写得很好,翻译一下,做个纪念.由于英文水平实在太烂,所以翻译有错或者译得不好的地方请多指正.另外由于原文是针对W ...
- WPF如何用TreeView制作好友列表、播放列表
WPF如何用TreeView制作好友列表.播放列表 前言 TreeView这个控件对于我来说是用得比较多的,以前做的小聊天软件(好友列表).音乐播放器(播放列表).类库展示器(树形类结构)等都用的是T ...
- A WPF/MVVM Countdown Timer
Introduction This article describes the construction of a countdown timer application written in C# ...
- 使用Prism提供的类实现WPF MVVM点餐Demo
使用Prism提供的类实现WPF MVVM点餐Demo 由于公司开发的技术需求,近期在学习MVVM模式开发WPF应用程序.进过一段时间的学习,感受到:学习MVVM模式,最好的方法就是用MVVM做几个D ...
- WPF MVVM使用prism4.1搭建
WPF MVVM使用prism4.1搭建 MVVM即Model-View-ViewModel,MVVM模式与MVP(Model-View-Presenter)模式相似,主要目的是分离视图(View)和 ...
- ViewModel从未如此清爽 - 轻量级WPF MVVM框架Stylet
Stylet是我最近发现的一个WPF MVVM框架, 在博客园上搜了一下, 相关的文章基本没有, 所以写了这个入门的文章推荐给大家. Stylet是受Caliburn Micro项目的启发, 所以借鉴 ...
随机推荐
- js中 字符串与Unicode 字符值序列的相互转换
一. 字符串转Unicode 字符值序列 var str = "abcdef"; var codeArr = []; for(var i=0;i<str.length;i++ ...
- oracle-删除归档日志
rman target user/password; DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7';
- 升级了win10后开启wifi热点出现iphone&macbook连接断线的问题(win7也一样)
升级了win10后开启wifi热点出现iphone&macbook连接 不间断 断线的问题 文后附上开启虚拟wifi的办法 百度参考了别人也出现这种问题,解决办法是修改信道,默认信道是11,修 ...
- MySQL常用技巧
1.查看MySQL版本信息: 1,登上 mysql>status; 2,登上 mysql>select version(); 3,登上 mysql> select @@version ...
- volatile与synchronized关键字
volatile关键字相信了解Java多线程的读者都很清楚它的作用.volatile关键字用于声明简单类型变量,如int.float.boolean等数据类型.如果这些简单数据类型声明为volatil ...
- 作为一个测试leader平时应该注意哪些方面
平时对管理方面很少有总结,总觉得管理是一门艺术,一门需要意会的艺术,虽然目前在做测试leader,平时也看些管理方面的书,但实际中总感觉理解的不够透彻,在工作上实施的话会有各种各样的情况,想要做好管理 ...
- 『转载』使用TortoiseSVN客户端
原文地址:https://www.sinacloud.com/doc/sae/tutorial/code-deploy.html#shi-yong-git-ke-hu-duan TortoiseSVN ...
- 边工作边刷题:70天一遍leetcode: day 88
Unique Word Abbreviation 要点: 简单题,主要是理解题意.no other words have the same abbreviation as the given word ...
- 利用OpenCV检测图像中的长方形画布或纸张并提取图像内容
基于知乎上的一个答案.问题如下: 也就是在一张照片里,已知有个长方形的物体,但是经过了透视投影,已经不再是规则的长方形,那么如何提取这个图形里的内容呢?这是个很常见的场景,比如在博物馆里看到一幅很喜欢 ...
- JAVA基础之对象的初始化
本文主要记录JAVA中对象的初始化过程,包括实例变量的初始化和类变量的初始化以及 final 关键字对初始化的影响.另外,还讨论了由于继承原因,探讨了引用变量的编译时类型和运行时类型 一,实例变量的初 ...