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项目的启发, 所以借鉴 ...
随机推荐
- Git 升级与基础适用
Git 升级 老方法 yum install git 目前centos6安装的 git 版本为1.7相对于 github 以及自己安装的 git 服务器都相对比较老,所以一般不适用此方法安装) 编译安 ...
- MSDE简介
MSDE的全程是Microsoft SQL Server Desktop Engine,它是一个基于 SQL Server 核心技术构建的数据引擎.MSDE 2000 支持单处理器和双处理器,是面向小 ...
- 手机打开PC端网址自动跳转到手机站代码
<script>function uaredirect(murl){ try { if(document.getElementById("bdmark") != nul ...
- phpcms v9 下拉菜单 二级 三级子栏目调用方法
很多网站的导航栏可以实现下拉二级菜单,三级菜单等效果,今天我们就来分享phpcms v9 支持下拉菜单的方法,可以支持无限子栏目调用,具体写法如下: <ul> {pc:content ac ...
- Hive query issue
One time, I have written a query with two tables join, One table is big table with partitions , anot ...
- dw websites
http://www.kimballgroup.com/data-warehouse-business-intelligence-resources/kimball-techniques/dimens ...
- [转]ionic $state.go passed $stateParams
本文转自:http://stackoverflow.com/questions/19516771/state-go-toparams-not-passed-to-stateparams If you ...
- [转]ASP.NET 2.0中GridView无限层复杂表头的实现
本文转自:http://blog.csdn.net/net_lover/article/details/1306211 实现方法就是给单元格填充我们想要的格式代码. C# <%@ Page La ...
- dos系统下mysql常用命令
show table status;//查看所有表状态,通过这个命令可以得知表的创建时间和最后更新时间,以及该表是基表还是视图以及是什么表引擎等信息. show table status from d ...
- Gitblit-Git版本服务器环境部署
Gitblit介绍 Gitblit 是一个纯 Java 库用来管理.查看和处理 Git 资料库.相当于 Git 的 Java 管理工具,支持linux系统. Git是分布式版本控制系统,它强调速度.数 ...