WPF MVVM之点滴分享
(第五点:绑定源有修改)
我并不打算长篇累牍的介绍什么是MVVM。我尽量简洁的介绍,并把自己的经验分享给大家。
一、关于MVVM
M:Model,数据模型(后台存储数据的类)
V:View,视图(大部分情况下就是窗体,用来与用户交互)
VM:ViewModel,视图模型。它的作用是连接Model与View,操作Model与View。
如图所示:(图片引用:走进WPF之MVVM完整案例 - 公子小六 - 博客园 (cnblogs.com))

二、MVVM的目的
MVVM的最主要的目的就是为了前后端分离。后台开发人员可以独立自主的开发所有的的功能需求,而不管界面如何设计;前端人员可以忽视后台的逻辑,只负责“美美哒”。
等两边都都完成后,只需要在界面上,进行相关的绑定就搞定。
当然,如果只是个人开发个小工具,且以后不一定维护的话,个人真的不建议使用MVVM。因为这种模式会将代码组织的比较复杂,代码也会变得很长。。。
但如果是团队开发,或者会长久的维护下去,倒是可以用这种模式,毕竟这种模式下,代码逻辑还是比较清晰的。
三、MVVM的主要手段
在传统的开发方式中,程序与用户的交互,大部分会使用“事件”这一特性。例如按钮的“单击”事件,textbox的“TextChanged”事件等。但如果使用事件,则必然会在窗体类中,增加很多事件处理程序,又必然会与后台的数据打交道。
如此一来,就很难将后台与前端分离。
为了解决这个问你题,MVVM模式使用“绑定”的方法。即ViewModel层,定义一些属性、命令、命令处理程序。当View层需要的时候,直接“绑定”这些属性、命令就可以。
因此,绑定,就成了MVVM最主要内容。
四、事件绑定
很多控件是支持命令的。例如Button,它有一个Command属性。如果对它进行绑定,当单击这个命令时,绑定的命令就会被触发。
但这又带来另外一个问题:Button的Command命令,只有在单击的时候才被触发。如果希望在双击它,或者按下它的时候,执行某些动作该怎么办呢?因为要实现前后端分离,那么在前端窗口类中,就不应该再写任何逻辑代码。
此时,就可以用到Interaction类了。它是微软预定义好的一些事件触发器。使得当事件被触发时,调用绑定的命令。
要使用该类,首先需要添加引用。使用Nuget,搜索Microsft.Xaml.Behaviors.Wpf,并安装。
然后在窗体类中倒入命名空间:xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
为需要的类添加事件触发器。以下代码,为Window类添加Drop事件触发器。
1 <Window x:Class="AppManagement.View.PortableAppWnd"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
6 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7 xmlns:local="clr-namespace:AppManagement"
8 mc:Ignorable="d"
9 Title="PortableApp Management" Name="window" Height="450" Width="800" Background="#3B3B3C"
10 Loaded="Window_Loaded" Closing="Window_Closing" AllowDrop="True" >
11
12 <!-- Drop事件 使用PassEventArgsToCommand将事件的参数,传递只命令-->
13 <i:Interaction.Triggers>
14 <i:EventTrigger EventName="Drop">
15 <i:InvokeCommandAction Command="{Binding DragDrop, Source={StaticResource ViewModel}}"
16 PassEventArgsToCommand="True"
17 CommandParameter="我写的"/>
18 </i:EventTrigger>
19 </i:Interaction.Triggers>
20
21 <Grid>
22 </Grid>
23 </Window>
备注:
1. 第5行:导入behaviors命名空间,并以字母 i 代替;
2. 第16行:绑定命令DragDrop,并指定命zrce)。命令实际上是继承了ICommand接口的类的对象。当命令被触发的时候,会调用该对象的Execute(objecet? parameter)方法。
3. 第17行:指示是否将事件的参数传递到过去;当PassEventArgsToCommand为True时,会将事件的处理程序的参数EventArgs类型的e,传递到Execute函数的parament;当设置为false时,则不会传递该参数。
4. 第18行:指定命令的参数(CommandParameter)。命令被触发时,会将它传递到Execute函数的parament,此时EventArgs无效。因此,如果在逻辑代码中需要用到EventArgs,则不要同时设置PassEventArgsToCommand为True。
五、绑定源
通常情况会,我们会把绑定源(数据源+命令源)赋值给某个控件的DataContext,然后进行绑定。但在对ContextMenu进行绑定时,这种绑定就不适用了。通过调试会发现,在Xaml中,ContextMenu与窗体平级别的,这意味着ContextMenu是没有逻辑上的父级,也没有视觉树上的父级,当把它绑定到命令的时,会找不到绑定源。
为了解决这个问题,有些文章提出,用代理模式。但是我们可以用这样一种方法:把绑定源做成静态资源写入到Xaml中。
看以下代码:
Xaml中
1 <Window x:Class="AppManagement.View.PortableAppWnd"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
6 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7 xmlns:local="clr-namespace:AppManagement"
8 mc:Ignorable="d"
9 Title="PortableApp Management" Name="window" Height="450" Width="800" Background="#3B3B3C"
10 Loaded="Window_Loaded" Closing="Window_Closing" AllowDrop="True" >
11
12 <Window.Resources>
13
14 <local:AppViewModel x:Key="ViewModel"/>
15
16 </Window.Resources>
17
18 <Grid>
19 <Button>
20 <Button.ContextMenu>
21 <ContextMenu>
22 <MenuItem Header="打开文件夹"
23 Command="{Binding OpenInFolder,Source={StaticResource ViewModel}}"
24 CommandParameter="{Binding}"/>
25
26 <MenuItem Header="删除" Command="{Binding DeleteApp,Source={StaticResource ViewModel}}"
27 CommandParameter="{Binding}"/>
28 </ContextMenu>
29 </Button.ContextMenu>
30 </Button>
31 </Grid>
第14行代码,定义了一个资源,它是AppViewModel的对象。它作为绑定源,集合了数据、命令。后面的代码都从这个资源中寻找绑定源。
第23行代码,命令绑定时,指定了Source是ViewModel,即从这个对象中去找命令。
第24行代码,只写了Binding,是因为它需要将对象本身作为参数传递到命令中,而不是传递对象的某个属性。
实际上,以为在Xaml中定义了资源,就相当于在程序中创建一个对象,因此,在窗口的后台代码中,不用再创建对象!
WPF MVVM之点滴分享的更多相关文章
- WPF MVVM 验证
WPF MVVM(Caliburn.Micro) 数据验证 书接前文 前文中仅是WPF验证中的一种,我们暂且称之为View端的验证(因为其验证规是写在Xaml文件中的). 还有一种我们称之为Model ...
- WPF MVVM初体验
首先MVVM设计模式的结构, Views: 由Window/Page/UserControl等构成,通过DataBinding与ViewModels建立关联: ViewModels:由一组命令,可以绑 ...
- WPF MVVM实现TreeView
今天有点时间,做个小例子WPF MVVM 实现TreeView 只是一个思路大家可以自由扩展 文章最后给出了源码下载地址 图1 图2 模版加上了一个checkbox,选中父类的checkb ...
- WPF/MVVM 快速开始指南(译)(转)
WPF/MVVM 快速开始指南(译) 本篇文章是Barry Lapthorn创作的,感觉写得很好,翻译一下,做个纪念.由于英文水平实在太烂,所以翻译有错或者译得不好的地方请多指正.另外由于原文是针对W ...
- 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项目的启发, 所以借鉴 ...
- WPF MVVM 架构 Step By Step(6)(把actions从view model解耦)
到现在为止,我们创建了一个简单的MVVM的例子,包含了实现了的属性和命令.我们现在有这样一个包含了例如textbox类似的输入元素的视图,textbox用绑定来和view model联系,像点击but ...
- Java解析OFFICE(word,excel,powerpoint)以及PDF的实现方案及开发中的点滴分享
Java解析OFFICE(word,excel,powerpoint)以及PDF的实现方案及开发中的点滴分享 在此,先分享下写此文前的经历与感受,我所有的感觉浓缩到一个字,那就是:"坑&qu ...
随机推荐
- Ubuntu 18.04 (Bionic) 简单快速的安装mongodb
按步骤走,不带脑子式安装(注意4.0版本mongodb官方已经不再支持,以下代码中可以修改mongodb版本号安装,目前最新版为6.0,如果懒得改直接用也可以,文章后边第三章第一条代码会直接升级为最新 ...
- 【操作日志】如何在一个SpringBoot+Mybatis的项目中设计一个自定义ChangeLog记录?
设计一个业务改动信息时的自定义记录,例如新增.修改.删除数据等.并且记录的规则可以通过配置的方式控制.大家需要根据各自业务场景参考,欢迎讨论.伪代码如下: 实体类: @TableName(" ...
- K8S | 核心原理分析
目录 一.背景 二.持续集成 三.K8S架构 1.核心组件 2.分层结构 3.核心能力 3.1 发现与负载 3.2 调度 3.3 自动伸缩 四.应用案例 1.服务部署 2.交互流程 五.参考源码 整体 ...
- 推送服务接入指导(HarmonyOS篇)
消息推送作为App运营日常使用的用户促活和召回手段,是与用户建立持续互动和连接的良好方式.推送服务(Push Kit)是华为提供的消息推送平台,建立了从云端到终端的消息推送通道,本文旨在介绍Harmo ...
- Gitlab恢复数据报错解决方法
背景 在Gitlab迁移恢复数据出现must be owner of extension plpgsql解决方法:在做gitlab迁移时,按正常Gitlab备份数据gitlab-rake gitlab ...
- 使用 InstructPix2Pix 对 Stable Diffusion 进行指令微调
本文主要探讨如何使用指令微调的方法教会 Stable Diffusion 按照指令 PS 图像.这样,我们 Stable Diffusion 就能听得懂人话,并根据要求对输入图像进行相应操作,如: 将 ...
- 4. Mybatis的增删改查(CRUD)
1.新增 <!--int insertUser();--> <insert id="insertUser"> insert into t_user va ...
- 未来的编程语言「GitHub 热点速览」
又一个编程语言火了,不算新,因为它已经开发了一段时间.不过在本周 Hacker News 上风头十足,DreamBerd 除了有点意思的改 ; 分隔符为 !,之外,它还能让你用问号来标注一段你也不确定 ...
- 记一次 .NET 某埋线管理系统 崩溃分析
一:背景 1. 讲故事 经常有朋友跟我反馈,说看你的文章就像看天书一样,有没有一些简单入手的dump 让我们先找找感觉,哈哈,今天就给大家带来一篇入门级的案例,这里的入门是从 WinDbg 的角度来阐 ...
- matlab转C++——C++中的矩阵运算和矩阵型函数
最近接到一个委托,把matlab代码转译为c++语言,看看能不能提高运行效率. matlab虽然本身具有将程序转化为C++的app库,但是对代码格式有严格的要求: 变量使用之前需要对变量类型和空间大小 ...