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 ...
随机推荐
- X86逆向9:通过关键常量破解
本章将讲解一下关于关键全局变量的一些内容,关键的全局变量对于软件的破解非常的有用,找到了关键全局变量并改写它同样可以完成完美爆破一个程序,这里我将使用CM小例子来讲解搜索关键变量的一些技巧,最后我们来 ...
- Java源码 HashMap<K,V>
HashMap类 https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html public class HashMap<K, ...
- 《深入理解 Java 虚拟机》学习 -- 垃圾收集器
<深入理解 Java 虚拟机>学习 -- 垃圾收集器 1. Serial 收集器(新生代) 含义: 单线程收集器. 缺点: 进行垃圾收集时,必须暂停其他所有的工作线程. 优点: 简单而高效 ...
- oracle创建用户表空间
--本次因工作需要,为其他部门提供部分表数据,创建一个新用户与表空间.--system用户下drop user sys_outside cascade;drop tablespace sys_outs ...
- 发明专利定稿&递交申请啦,开心
也不想写些什么,只是想简单的分享一下当前的心情! 第一版到最后一版中间因为各种事情耽误,一直弄到现在.5月中旬找的专利代理局中间连续修改很多次,从大改到小改,再到微调真的是学习到了! 下面就是搞定&l ...
- Zend 3.3.0安装 ZendOptimizer 3.3.0 for Windows 稳定版 下载
用的某php网站系统今天打开时乱码了(zend 200407...),但phpmyadmin能正常使用: 搜索下,重新安装zend可以解决,系统上原来的版本是Zend 3.3.0:下了个,安装后果然把 ...
- Flink概述
计算引擎 大数据计算引擎分为离线计算和实时计算,离线计算就是我们通常说的批计算,代表是Hadoop MapReduce.Hive等大数据技术.实时计算也被称作流计算,代表是Storm.Spark St ...
- bash 中 () {} [] [[]] (()) 的解释
bash 中 () {} [] [[]] (()) 的解释 来源 https://www.cnblogs.com/fhefh/archive/2011/04/16/2017895.html bash ...
- 修改NPM默认全局安装路径
场景: 最近在新电脑上鼓捣完环境后,打算切换下源,结果使用全局安装的nrm时提示找不到命令,之前都是这么用现在怎么不行了呢? 排查过程: 于是各种折腾,发现- g安装的插件目录在C盘中的某个路径中,后 ...
- Java 单个集合去重与两个集合去重
一.单个集合去重 描述: 去掉一个集合里重复的元素:将list集合转成hashSet集合,hashSet有自动去重的功能,再利用去重后的hashSet集合初始化一个新的list集合,此时这个list就 ...