WPF之Treeview实现MVVM双向绑定
Treeview分别有两个数据模板HierarchicalDataTemplate(层级数据模板)和DataTemplate(数据模板),分别应用于生成子数据项和普通数据项。
在使用过程中,如果对两个模板的DataType设置为同一类型,运行时会直接报错。

大概原因是添加了俩个相同Key的资源(因为HierarchicalDataTemplate和DataTemplate都是定义在<TreeView.Resources>标签中)。
代码:
public class TypeTreeModel :TypeModel
{
public ObservableCollection<TypeTreeModel> ChildList { get; set; }
= new ObservableCollection<TypeTreeModel>();
}
public class TypeModel
{
public int Id { get; set; }
public string Name { get; set; }
}
<TreeView x:Name="treeView" ItemsSource="{Binding TypeList}" MinWidth="200" MaxHeight="200" >
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vm:TypeTreeModel}" ItemsSource="{Binding ChildList}">
<TextBlock Text="{Binding Name}" Margin="3 2"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type vm:TypeModel}">
<TextBlock Text="{Binding Name}" ToolTip="{Binding Id}" Margin="3 2"></TextBlock>
</DataTemplate>
</TreeView.Resources>
</TreeView>
效果图:

TypeList一般都是数据库取出来的数据处理嵌套后的结果。有时候会遇到需求,对于不同的分类有不同的类型。根据双向绑定的规则,我们只需要修改ViewModel中TypeList的内容就可以了。
注意: ObservableCollection只有在列表项发生变化时才会触发页面刷新,即新增或删除时才会反应到页面上。若采用直接赋值的写法,不会触发页面刷新。
推荐更新数据时候的写法:
//清空原先的列表
TypeList.Clear();
list.ForEach(d =>
{
TypeList.Add(d);
});
TreeView.SelectedItem双向绑定
TreeView.SelectedItem是ReadOnly的,所以不能通过简单的绑定方法去获取选中项
最终还是要通过绑定Treeview的SelectedItemChanged事件,来修改ViewModel中的数据
1.直接绑定事件
<TreeView ItemsSource="{Binding TypeList}" SelectedItemChanged="TreeView_OnSelectedItemChanged" />
private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
vm.SelectItem = (Cluster)e.NewValue;
}
2.通过Command绑定事件
- 在项目中引用
System.Windows.Interactivity.WPF(简单来说该插件可以将页面控件的Event转为ViewModel中的Command) - 在窗体中添加引用
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
- 绑定
Command到SelectedItemChanged事件
<TreeView x:Name="treeView" ItemsSource="{Binding TypeList}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction Command="{Binding SelectItemChangeCommand}"
CommandParameter="{Binding ElementName=treeView,Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TreeView>
ViewModel:
public class TreeViewModel : ViewModelBase
{
public ObservableCollection<TypeTreeModel> TypeList;
private TypeModel selectItem;
public TypeModel SelectItem
{
get { return selectItem; }
set { this.MutateVerbose(ref selectItem, value, RaisePropertyChanged()); }
}
public TreeViewModel()
{
TypeList = GetData();
}
public ICommand SelectItemChangeCommand
{
get
{
return new CommandBase((param) =>
{
if(param != null)
SelectItem = (TypeModel)param;
});
}
}
}
效果图:

ViewModelBase和CommandBase是自己封装的基类,就是为了写WPF的双向绑定简单点,有兴趣的可以评论向我要。
Demo地址: https://github.com/fxhui/TreeViewDemo
WPF之Treeview实现MVVM双向绑定的更多相关文章
- WPF之AvalonEdit实现MVVM双向绑定
AvalonEdit简介 AvalonEdit是基于WPF开发的代码显示控件,默认支持多种不同语言的关键词高亮,并且可以自定义高亮配置.所以通过AvalonEdit可以快速开发出自己想要的代码编辑器. ...
- 【.NET6+WPF】WPF使用prism框架+Unity IOC容器实现MVVM双向绑定和依赖注入
前言:在C/S架构上,WPF无疑已经是"桌面一霸"了.在.NET生态环境中,很多小伙伴还在使用Winform开发C/S架构的桌面应用.但是WPF也有很多年的历史了,并且基于MVVM ...
- 【Maui正式版】创建可跨平台的Maui程序,以及有关依赖注入、MVVM双向绑定的实现和演示
前言:Maui终于在昨天(2022年8月9日)推送出来了.今儿就迫不及待来把玩一下先. A.我本地已有VS2022,不过版本比较老,此处选择更新.工具 -> 获取功能和更新里面,可以获取到新版本 ...
- C#使用Xamarin开发可移植移动应用(3.进阶篇MVVM双向绑定和命令绑定)附源码
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 嗯..前面 ...
- C#使用Xamarin开发可移植移动应用(4.进阶篇MVVM双向绑定和命令绑定)附源码
前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 嗯..前面 ...
- 仿vue实现简易版mvvm双向绑定
项目地址:https://github.com/pangyongsheng/mvvm 1. 指令 vm-bind 单选数据绑定- 将数据显示到标签视图 vm-model : 双向数据绑定 vm-sho ...
- mvvm双向绑定机制的原理和代码实现
mvvm框架的双向绑定,即当对象改变时,自动改变相关的dom元素的值,反之,当dom元素改变时,能自动更新对象的值,当然dom元素一般是指可输出的input元素. 1. 首先实现单向绑定,在指定对象的 ...
- MVVM双向绑定实现之Object.defineProperty
随着web应用的发展,直接操作dom的应用已渐行渐远,取而代之的是时下越来越流行的MVVM框架,dom操作几乎绝迹,这里面自然是框架底层封装的结果.MVVM框架的双向数据绑定使开发效率大大提高:然后在 ...
- 【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
前言: Wpf开发过程中,最经常使用的功能之一,就是用户控件(UserControl)了.用户控件可以用于开发用户自己的控件进行使用,甚至可以用于打造一套属于自己的UI框架.依赖属性(Dependen ...
随机推荐
- Fiddler之WebFroms的中文乱码问题
乱码问题:修改注册表 1.windows+R ,输入regedit ,按enter键 2.进入这个目录:HKEY_CURRENT_USER\Software\Microsoft\Fiddler2 3. ...
- Dreamoon and Strings CodeForces - 477C (字符串dp)
大意: 给定字符串$s$, $p$, 对于$0\le x\le |s|$, 求$s$删除$x$个字符后, $p$在$s$中的最大出现次数. 显然答案是先递增后递减的, 那么问题就转化求最大出现次数为$ ...
- Aveva Marine C# 二次开发入门001
1# 引用 C:\AVEVA\Marine\OH12.1.SP4\Aveva.ApplicationFramework.dll C:\AVEVA\Marine\OH12.1.SP4\Aveva.App ...
- Web应用性能分析工具—HAR文件
Web应用性能分析工具—HAR文件 来源 https://raynorli.com/2018/06/11/web-performance-analysis-har-file/ 客户经常有的一个问题就是 ...
- python之数字类型小知识
数字是表示计数的抽象事物,也是数学运算和推理的基础,所以,生活中数字是生活中无处不在的,那么,在python语言中运用数字有哪些小知识呢,不妨花点时间看一下这篇博文,牢记这些小知识. 整数类型中四种进 ...
- span 如何移除点击事件
//设置点击事件不可用 $("#verificode").css("pointer-events", "none"); //倒计时完毕,点击 ...
- 【漏洞分析】Discuz! X系列全版本后台SQL注入漏洞
0x01漏洞描述 Discuz!X全版本存在SQL注入漏洞.漏洞产生的原因是source\admincp\admincp_setting.php在处理$settingnew['uc']['appid' ...
- 解决 /etc/init.d/php-fpm no such file or directory等相关问题
vi /etc/init.d/php-fpm #! /bin/sh # Comments to support chkconfig on CentOS # chkconfig: 2345 65 37 ...
- Cowrie蜜罐部署教程
0.蜜罐分类: 低交互:模拟服务和漏洞以便收集信息和恶意软件,但是攻击者无法和该系统进行交互: 中等交互:在一个特有的控制环境中模拟一个生产服务,允许攻击者的部分交互: 高交互:攻击者可以几乎自由 ...
- 建立一个能持续处理的C/S网络程序
程序流程图: 代码演示: 服务器端: #include<WinSock2.h> #include<Windows.h> #include<stdio.h> #inc ...