MVVM Light 一个窗口承载两个视图

 

原文地址:http://www.codeproject.com/Articles/323187/MVVMLight-Using-Two-Views

本文并不是对原文逐句翻译,为了尽量通俗易懂,本人对原文有所增删。

如果你对MVVM还不太熟悉可以先看看本人之前的关于MVVM的博客:

http://www.cnblogs.com/zhangzhi19861216/archive/2013/03/19/WPF-MVM.html

如果你对MVVMLight不太了解,在阅读本文前,最好先阅读本人之前的一片译文:

http://www.cnblogs.com/zhangzhi19861216/archive/2013/03/20/2971400.html

在之前的文章中,我快速展示了如何用MVVMLight创建一个单View、单Window的WPF应用程序。但是WPF应用程序的趋势是一个窗口承载多个视图,

以便减少弹出的对话框或子窗口。本文展示了用MVVM模式构建一个简单的一个窗口承两个视图的应用程序。

在开始之前:

1、 需要VS2010

2、 确保你安装了NUget

3、 用Manage Nuget Package 引用并且添加 MVVM Light。

4、 这篇文章的源码在 github上。

注意,为了简洁起见,博文中的很多代码,特别是Xaml省略了,所以读者最好去github下载源码进行阅读。

承载多个视图

这个应用程序的结构类似之前的文章,我们有个MainWindow,ViewModelLocator和MainViewModel。

一张图片胜过千言万语,所以事不宜迟,这里是VS2010中的项目结构视图:

该项目为典型的MVVM风格:3个文件夹分别为Model,ViewModel和View。在当前项目,我们没有任何的Model,因此它可以忽略不计。

我们从View开始:在Views文件夹下我们创建两个UserControl——FirstView.xaml和SecondView.xaml。

FirstView.xaml和我们上篇文章 一致,而SecondView.xaml仅包含一个Lable元素。

所有涉及两个视图切换的操作都在MainViewModel.cs, MainWindow.xaml, and App.xaml当中.

首先看看MainWindow XAML,如下所示:

<Window x:Class="TwoViews.MainWindow"
DataContext="{Binding Main,
Source={StaticResource Locator}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions> <ContentControl Content="{Binding CurrentViewModel}" /> <DockPanel Grid.Row="1" >
<Button Command="{Binding SecondViewCommand}"
Content="Second View"
DockPanel.Dock="Right" />
<Button Command="{Binding FirstViewCommand}"
Content="First View"
DockPanel.Dock="Left" />
</DockPanel>
</Grid>
</Window>

看上面的代码,像之前一样,我们使用ViewModelLocator绑定我们的Main  视图模型到MainWindow。然而,这一次,我们有一个ContentControl绑定到一个称为CurrentViewModel(定义在MainViewModel当中)的新属性,并且有两个按钮分别绑定一个命令。

获取源码(译者所建项目):

files.cnblogs.com/zhangzhi19861216/ MVVMLigntStudy.rar

我们打开项目运行一下:

(First View)

(Second View)

我们看到,当分别点击按钮,有两个View在切换(实际上是我们的ViewModel在更新)。

让我们来看看MainViewModel.cs的代码:

 public class MainViewModel : ViewModelBase
{ private ViewModelBase _currentViewModel; readonly static SecondViewModel _secondViewModel = new SecondViewModel(); readonly static FirstViewModel _firstViewModel = new FirstViewModel(); public ViewModelBase CurrentViewModel
{
get
{
return _currentViewModel;
}
set
{
if (_currentViewModel == value)
return;
_currentViewModel = value;
RaisePropertyChanged("CurrentViewModel");
}
} public ICommand FirstViewCommand { get; private set; } public ICommand SecondViewCommand { get; private set; } public MainViewModel()
{
CurrentViewModel = MainViewModel._firstViewModel;
FirstViewCommand = new RelayCommand(() => ExecuteFirstViewCommand());
SecondViewCommand = new RelayCommand(() => ExecuteSecondViewCommand());
} private void ExecuteFirstViewCommand()
{
CurrentViewModel = MainViewModel._firstViewModel;
} private void ExecuteSecondViewCommand()
{
CurrentViewModel = MainViewModel._secondViewModel; ;
}
}

MainViewModel定义了三个ViewModel(_currentViewModel、_secondViewModel 、_firstViewModel),和两命令(FirstViewCommand,SecondViewCommand),两个命令分别调用如下两个方法:

private void ExecuteFirstViewCommand()
{
CurrentViewModel = MainViewModel._firstViewModel;
} private void ExecuteSecondViewCommand()
{
CurrentViewModel = MainViewModel._secondViewModel; ;
}

每次触发命令(点击FirstView或者SecondView按钮),其实都是在_firstViewModel和_secondViewModel之间切换——把它们赋给CurrentViewModel,而MainWindow.xaml中的ContentControl元素绑定的就是CurrentViewModel,因此跟着更新。

疑惑:ViewModel之间的切换,如何引起View的不同显示呢?

接下来看看App.xaml:

<Application x:Class="TwoViews.App"
xmlns:views="clr-namespace:TwoViews.Views"
xmlns:vm="clr-namespace:TwoViews.ViewModels"
StartupUri="MainWindow.xaml"
>
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" />
<DataTemplate DataType="{x:Type vm:SecondViewModel}">
<views:SecondView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:FirstViewModel}">
<views:FirstView />
</DataTemplate>
</Application.Resources>
</Application>

在这里,我们使用DataTemplate 将ViewModel通过View表现出来。

例如,毫不夸张地说:“如果我的数据类型应该是FirstViewModel,那么WPF框架应该呈现的是FirstView用户控件。

译者注:在WPF中我们可以使用DataTemplate为自己的数据(视图模型中的数据)定制显示方式,也就是说虽然某数据数据是一定的,

但我们可以做到(通过View)让它的表现方式多种多样。

本文就翻译到这里,翻译的章节次序和原文不太相符。因为我觉得这样更容易理解。

如果文中出现错误或者歧义,请指正。

译文源码:files.cnblogs.com/zhangzhi19861216/ MVVMLigntStudy.rar

原文源码:https://github.com/barrylapthorn/MvvmLightExamples

译者注:

看到原文下面留言:Nothing to download? 估计是进入原文源码下载页面,读者找不到源码下载地址。

提示:进入原文下载页面后,点击Zip按钮即可,这主要是很多读者对github不太熟悉。

如果你对MVVMLight感兴趣,而你的英文实在不怎么好,推荐你阅读如下国内作者的博客:

http://www.cnblogs.com/phoenixtrees/archive/2011/05/01/2033847.html

http://blog.csdn.net/duanzilin/article/details/6387639

接下来我还会翻译更多关于WPF的文章,希望大家多多支持,多交流。

MVVM Light 一个窗口承载两个视图的更多相关文章

  1. 一个ActionResult中定位到两个视图—<团委项目>

         在使用MVC做项目的时候一般的情况就是一个ActionResult一个视图,这样对应的Return View();就可以找到下面对应的视图,这是根据一个原则,"约定大于配置&quo ...

  2. 一个ActionResult中定位到两个视图—<团委项目>

    在使用MVC做项目的时候一般的情况就是一个ActionResult一个视图,这样对应的Return View();就可以找到下面对应的视图,这是根据一个原则,“约定大于配置”,但是我们有的时候需要在一 ...

  3. MVVM Light 新手入门(3) :ViewModel / Model 中定义“事件” ,并在View中调用 (无参数调用)

    今天学习MVVM架构中“事件”的添加并调用,特记录如下,学习资料均来自于网络,特别感谢翁智华 的 利刃 MVVMLight 6:命令基础 在MVVM Light框架中,事件是WPF应用程序中UI与后台 ...

  4. Mvvm Light Toolkit 入门

    原文:Mvvm Light Toolkit 入门 前言 之前学习UWP的时候就一直看到有关MVVM的资料但是一直没有系统的去学,最近正好有时间,特地来攻破这个点,顺便学习一下VS与GitHub的链接和 ...

  5. 【MVVM Light】Messager的使用

    一.前言       在MVVM编程的模式中,有时候我们会遇到一个很尴尬的情况: 若干个xaml.cs都复用一个ViewModel,当ViewModel想传递一个特定的消息给某一个xaml.cs的时候 ...

  6. Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架

    Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架   本章节,我将通过示例介绍如何搭建mvvmlight开发环境.示例中的我会针对wpf ...

  7. MVVM Light须要注意的10个问题

    MVVM Light须要注意的10个问题 从使用XAML技术基础開始(实际上并非非常久曾经).我便关注MVVM(Model – View – ViewModel)模式.偶然接触到MVVM Light不 ...

  8. WPF: WpfWindowToolkit 一个窗口操作库的介绍

    在 XAML 应用的开发过程中,使用MVVM 框架能够极大地提高软件的可测试性.可维护性.MVVM的核心思想是关注点分离,使得业务逻辑从 View 中分离出来到 ViewModel 以及 Model ...

  9. MVVM Light Toolkit使用指南

    原文:MVVM Light Toolkit使用指南 原文地址:  https://blog.csdn.net/ldld1717/article/details/77040077 概述 MVVM Lig ...

随机推荐

  1. Hyper-V性能-CPU分配

    为新部署的微软Hyper-V环境中的主机和网络挑选合适的硬件并非易事,更不用说在生产环境中衡量和监控性能这项任务了.在这里,我和大家谈谈服务器的核心CPU与Hyper-V的结合是如何相得益彰的. 我接 ...

  2. C# DataTable的詳細使用方法

    在项目中经经常使用到DataTable,假设DataTable使用得当,不仅能使程序简洁有用,并且可以提高性能,达到事半功倍的效果,现对DataTable的使用技巧进行一下总结. 一.DataTabl ...

  3. 跟我一起学extjs5(05--主界面上增加顶部和底部区域)

    跟我一起学extjs5(05--主界面上增加顶部和底部区域)         这一节为主界面加一个顶部区域和底部区域. 一个管理系统的界面能够粗分为顶部标题部分.中间数据展示和处理的部分.底部备注和状 ...

  4. 为 vsftpd 启动 vsftpd:500 OOPS: bad bool value in config file for: pasv_enable

    每行的值都不要有空格,否则启动时会出现错误,举个例子,假如我在listen=YES后多了个空格,那我启动时就出现.. 为 vsftpd 启动 vsftpd:500 OOPS: bad bool val ...

  5. Java基础知识强化之IO流笔记62:三种方式实现键盘录入

    1. 三种方式实现键盘录入     System.in 标准输入流.是从键盘获取数据的 键盘录入数据三种方式:  A:main方法的args接收参数.  java HelloWorld hello w ...

  6. linux下如何删除文件夹

    直接rm就可以了,不过要加两个参数-rf 即:rm -rf 目录名字-r 就是向下递归,不管有多少级目录,一并删除-f 就是直接强行删除,不作任何提示的意思删除文件夹实例: rm -rf /var/l ...

  7. webform 转 MVC 飞一般的感觉

    前言: 浅谈webform与mvc,让开发变得更加简单,这里主要通过比较webform与mvc的开发方式,以下全属个人看法,不完善的地方可以留言补充. 正文: 废话不多说,直接说工作中经常用到的地方 ...

  8. MVC小系列(十五)【MVC+ZTree实现对树的CURD及拖拽操作】

    根据上一讲的可以加载一棵大树,这讲讲下如果操作这颗大树 <link href="../../Scripts/JQuery-zTree/css/zTreeStyle/zTreeStyle ...

  9. java swing窗口放置屏幕中央问题思考

    java swing窗口放置屏幕中央问题思考 以前总是尝试各种方法都没有能把组件放到屏幕中央,只能用死办法,设置绝对坐标,但这样就失去了可移植性,而且繁琐.今天仔细思考了一番,终于被我找出问题所在. ...

  10. OC - 12.NSURLRequest与NSURLConnection

    ##NSURLRequest NSURLRequest封装了一次网络请求所需要的数据,主要封装了以下信息: 请求路径(URL) 请求方法(GET或POST) 请求头 请求体 超时参数 NSURLReq ...