WPF之MVVM模式(1)
MVVM模式
一、MVVM模式概述
MVVM Pattern : Model\View\ViewModel
View:视图、UI界面
ViewModel:ViewModel是对Model的封装,通过一系列属性暴露Model的状态,提供给View进行显示
Model:数据模型
使用MVVM模式可以将代码逻辑和UI进行分离,因此开发团队可以关注创建健壮的ViewModel类,而设计团队可以关注设计界面友好的View。要融合两个团队输出只需要在View的xaml上进行正确的绑定即可。
二、演示程序
下面通过一个Demo演示WPF中如何使用MVVM模式:使用WPF中的data template、commands、data binding、resource结合MVVM模式,创建一个简单、可测试、健壮的框架。
演示程序结构图如下:

1、演示程序 Demo界面如图所示:

工作区用于显示视图
命令区分两部分,上部分为显示单视图命令,下部分为显示多视图命令
单视图:工作区始终只显示一个视图。
多视图:工作区可以显示多个视图,以TabControl控件的TabItem进行展示。可以通过previousview命令显示视图集合中的上一个视图,通过nextview显示视图集合中的下一个视图。
Demo的MainWindow.xaml文件中,使用单视图时,需要注释多视图;使用多视图时,需要注释单视图。代码如下:
<!--single view-->
<ContentPresenter Content="{Binding Path=WorkspaceSingle}"/> <!--multi view-->
<ContentPresenter Content="{Binding Path=WorkspaceMulti}" ContentTemplate="{StaticResource WorkspacesTemplate}"/>
三、数据模型(Model)、视图(View)
为了使Demo更容易理解,程序中只使用了一个Model,Model中Name属性用于显示视图名称。
public class InfoModel
{
//视图名称
public string Name { get; set; }
}
两个简单的视图:FirstView、SecondView,视图中控件显示当前的视图名称,如视图FirstView:

<StackPanel Background="Aqua">
<TextBlock Text="{Binding Path=Name}" FontSize=""/>
</StackPanel> <StackPanel Background="Chartreuse">
<TextBlock Text="{Binding Path=Name}" FontSize=""/>
</StackPanel>
在实际开发中,视图中可以布局其它控件,并进行正确的绑定,界面都能正常的显示。
显示多视图时,TabItem的Header能显示视图名称,如图所示:

视图名称DisplayName是基类ViewModelBase的属性
/// <summary>
/// 名称
/// </summary>
public virtual string DisplayName { get; protected set; }
子类在构造函数中给DisplayName赋值
public class FirstViewModel : WorkspaceViewModel
{
private const string DisplayViewName = "FirstView"; private readonly InfoModel _info; public FirstViewModel()
{
//视图名称
base.DisplayName = DisplayViewName; if (_info == null)
{
_info = new InfoModel();
}
_info.Name = DisplayViewName;
} public string Name
{
get { return _info.Name; }
}
}
在View中绑定视图名称
<DataTemplate x:Key="TabItemTemplate">
<DockPanel>
<ContentPresenter Content="{Binding Path=DisplayName}" VerticalAlignment="Center"/>
</DockPanel>
</DataTemplate>
四、ViewModel类图
大家一看代码就知道,整个ViewModel使用的是什么设计模式

五、View对应ViewModel
Demo的一个主要特点是数据延迟加载,即在需要数据时创建ViewModel
程序在启动时即为主界面加载数据MainWindowViewModel
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindow window = new MainWindow();
var viewModel = new MainWindowViewModel();
window.DataContext = viewModel;
window.Show();
}
}
程序启动后,单击按钮时创建FirstViewModel或SecondViewModel
创建单视图
/// <summary>
/// 显示视图一
/// </summary>
private void ShowFirstView()
{
if (_workspaceStory == null)
{
_workspaceStory = new ObservableCollection<WorkspaceViewModel>();
} var model =
this._workspaceStory.FirstOrDefault(vm => vm is FirstViewModel)
as FirstViewModel; if (model == null)
{
model = new FirstViewModel();
_workspaceStory.Add(model);
} WorkspaceSingle = model;
} /// <summary>
/// 显示视图二命令
/// </summary>
private void ShowSecondView()
{
if (_workspaceStory == null)
{
_workspaceStory = new ObservableCollection<WorkspaceViewModel>();
} var model =
this._workspaceStory.FirstOrDefault(vm => vm is SecondViewModel)
as SecondViewModel; if (model == null)
{
model = new SecondViewModel();
_workspaceStory.Add(model);
} WorkspaceSingle = model;
}
创建多视图
/// <summary>
/// 创建视图一,并显示
/// </summary>
private void CreateFirstView()
{
var model = new FirstViewModel();
WorkspaceMulti.Add(model);
ShowCurrentView(model);
} /// <summary>
/// 创建视图二
/// </summary>
private void CreateSecondView()
{
var model = new SecondViewModel();
WorkspaceMulti.Add(model);
ShowCurrentView(model);
}
创建后,WPF自动为匹配的View Model寻找View来渲染。
<DataTemplate DataType="{x:Type vm:FirstViewModel}">
<vw:FirstView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SecondViewModel}">
<vw:SecondView/>
</DataTemplate>
六、总结
MVVM模式是设计和开发WPF程序一种简单、有效的指导方针。它允许你创建数据、行为和展示强分离的程序,更容易控制软件开发中的混乱因素。
WPF之MVVM模式(1)的更多相关文章
- 【WPF】MVVM模式的3种command
原文:[WPF]MVVM模式的3种command 1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand 因为MVVM模式适合于WPF和SL, ...
- WPF之MVVM模式讲解
WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时,WPF会自动发出通知去更新UI. 恰当的模式可以让我们轻松达到“高内聚 ...
- 【转】【WPF】MVVM模式的3种command
1.DelegateCommand 2.RelayCommand 3.AttachbehaviorCommand 因为MVVM模式适合于WPF和SL,所以这3种模式中也有一些小差异,比如RelayCo ...
- WPF之MVVM模式(2)
我们都想追求完美 Every view in the app has an empty codebehind file, except for the standard boilerplate cod ...
- WPF中MVVM模式的 Event 处理
WPF的有些UI元素有Command属性可以直接实现绑定,如Button 但是很多Event的触发如何绑定到ViewModel中的Command呢? 答案就是使用EventTrigger可以实现. 继 ...
- WPF之MVVM模式(3)
有种想写一个MVVM框架的冲动!!! 1.Model中的属性应不应该支持OnPropertyChanged事件? 不应该.应该有ViewModel对该属性进行封装,由ViewModel提供OnProp ...
- WPF中 MVVM模式的Slider Binding.
对于Button的Command的绑定可以通过实现ICommand接口来进行,但是Slider并没有Command属性. 另外如果要实现MVVM模式的话,需要将一些Method和Slider的Even ...
- WPF采用MVVM模式(绑定:纯前台、命令:触发器绑定命令)
MVVM绑定 view-viewModel-model,模型介绍省略,就是创建类,添加字段封装属性.注:控件的绑定只能绑定到属性上,不能绑定到字段上: 接下来就是代码 (view): <Wind ...
- WPF中MVVM模式下控件自有的事件绑定
1.原因 在WPF中单纯的命令绑定往往不能满足覆盖所有的事件,例如ComboBox的SelectionChanged事件,DataGrid的SelectionChanged事件等等,这时就可以用事件绑 ...
随机推荐
- 转:django关于csrf防止跨站的ajax请求403处理
http://blog.csdn.net/wjy397/article/details/49078099
- JS计算字符串的长度
最近项目上经常要用到计算字符串的长度的问题,有时需要按照byte进行计算长度,所以我就想在页面上用js实现,于是就到网上查了相关的资料,发现确实有很多的版本,这里给出两个比较好用的. //方法一:逐个 ...
- [转]200 OK (from cache) 与 304 Not Modified------没有这个规则(ETag是否移除)!!!from cache和304,请查看顶部的流程图!
//========没有这个规则(ETag是否移除) 20160422============// 200 OK (from cache) 与 304 Not Modified 为什么有的缓存是 20 ...
- Spring 学习一 @Autowired
@Autowired Spring 2.5 引入了 @Autowired ,它可以对类成员变量.方法及构造函数进行标注,完成自动装配的工作. 通过 @Autowired的使用来消除 set ,get方 ...
- C#字符串全排序
排列:从n个元素中任取m个元素,并按照一定的顺序进行排列,称为排列: 全排列:当n==m时,称为全排列: 比如:集合{ 1,2,3}的全排列为: { 1 2 3} { 1 3 2 } { 2 1 3 ...
- Celery-4.1 用户指南: Optimizing (优化)
简介 默认的配置做了很多折中考虑.它不是针对某个情况优化的,但是大多数情况下都工作的非常好. 基于一个特殊的使用场景,有很多优化可以做. 优化可以应用到运行环境的不同属性,可以是任务执行的时间,使用的 ...
- 如何设置select下拉禁止选择
转自:https://blog.csdn.net/you23hai45/article/details/52233207
- 地图投影的N种姿势(转载)
转载地址:http://blog.sina.com.cn/s/blog_517eed9f0102w4rm.html 一篇题为<我们看到的地图一直都错得离谱……>的文章在朋友圈里莫名流行起来 ...
- elmah数据库sql脚本
/* 错误管理工具 SQL代码 */CREATE TABLE dbo.ELMAH_Error( ErrorId UNIQUEIDENTIFIER NOT NULL, Application NVARC ...
- PROCEDURE存储过程传入表参数
) ,itemNum ) ,itemQty )) ---2.创建一个存储过程以表值参数作为输入 alter proc usp_TestProcWithTable @tb LocationTa ...