`
pcajax
  • 浏览: 2200916 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MVVM教程(2):

 
阅读更多
在上一章中,我们只是开了个头而已,然而在这一章中,我们将看到一点实际的代码了。我构想了很久,怎样让新手能快速掌握我想要传达的知识,然后我得出一个结论:一定一定要简单化,并且要有看的见摸的着的代码实例。好吧,我们开始。

打开你的VS2010,新建一个WPF项目,命名为MvvmTutorial即可。紧接着,在当前Solution添加4个文件夹,分别为:Infrastructure, Views, ViewModels, Models。然后,把App.xaml改成如下:
<Application x:Class="MvvmTutorial.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
</Application >

把MainWindow.xaml,MainWindow.xaml.cs删掉。在Views下添加一个新的WPF Window,命名为ShellView。在App.xaml.cs中加入:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var shell = new ShellView();
shell.Show();
}

都完成了吗?现在按F5,你应该可以看到你的程序正常运行,并且已经可以看到主窗体了。至此,我们只是做了一些准备工作。Shell其实就是壳的意思,每一个Windows程序都会有一个主窗体,也就是一个壳,我们在这个壳上面拼凑各种View来构成一个丰富的应用程序。

现在我们来看一下具体我们要做些什么。我说过,尽量简单化,所以我们这章的任务很简单:就是把一些联系人显示在主窗体里。我们的联系人很简单,只有两个属性:名字和电话号码。我个人喜欢从ViewModel这一层出发,但是许多朋友还是习惯从Model层写起,那么我们就先来研究一下Model,即实体。在第一章中有人问是否应该在Model里实现INotifyPropertyChanged接口,我个人认为这个没有特别的死的做法。有点人愿意把Model尽量简单化,也就是说只是一个数据的载体而已,而把所有与View打交道的事情全部推给ViewModel。然而对于我们这个简单的例子,我选择让Model也实现INotifyPropertyChanged接口,如此一来,当我们对Model做出修改后,View上就可以显示出变化了(不过在今天这一章里,我们暂时不讨论ViewModel/Model的修改)。现在,在Models下添加一个Contact类。

我们的Model,很简单,具体是这个样子的:
using MvvmTutorial.Infrastructure;

namespace MvvmTutorial.Models
{
/// <summary >
/// Our Contact model, which stores data retrieved from data persistence layer
/// </summary >
public class Contact : ObservableObject
{
#region Fields

string _name;
string _phoneNumber;

#endregion // Fields

#region Properties

public string Name
{
get
{
return _name;
}
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged(() = > Name);
}
}
}

public string PhoneNumber
{
get
{
return _phoneNumber;
}
set
{
if (_phoneNumber != value)
{
_phoneNumber = value;
RaisePropertyChanged(() = > PhoneNumber);
}
}
}

#endregion // Properties
}
}

你们可能注意到了这个Contact实际上继承了ObservableObject。这是一个抽象的基类,由于我们将来会有很多类都要实现INotifyPropertyChanged接口,所以我在这里写了一个基类。在Infrastructure下添加一个ObservableObject:

using System;
using System.ComponentModel;
using System.Linq.Expressions;

namespace MvvmTutorial.Infrastructure
{
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

public virtual void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

public void RaisePropertyChanged<T >(Expression<Func<T > > propertyExpression)
{
var propertyName = PropertySupport.ExtractPropertyName(propertyExpression);
this.RaisePropertyChanged(propertyName);
}
}
}

好的,这里我要说一下,其实这个类不是我个人写的,而是“剽窃”了一些现有的开源代码,拼凑起来的。请注意PropertySupport,这是一个静态类,它其实来自于微软的Prism框架里一小段代码,我之所以这样做只是让大家看的更清楚这些MVVM的框架内部大体是怎么回事,其实都是大同小异的。请在Infrastructure下添加PropertySupport:
using System;
using System.Linq.Expressions;
using System.Reflection;

namespace MvvmTutorial.Infrastructure
{
public static class PropertySupport
{
public static string ExtractPropertyName<T >(Expression<Func<T > > propertyExpression)
{
if (propertyExpression == null)
{
throw new ArgumentNullException("propertyExpression");
}

var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("The expression is not a member access expression.", "propertyExpression");
}

var property = memberExpression.Member as PropertyInfo;
if (property == null)
{
throw new ArgumentException("The member access expression does not access a property.", "propertyExpression");
}

var getMethod = property.GetGetMethod(true);
if (getMethod.IsStatic)
{
throw new ArgumentException("The referenced property is a static property.", "propertyExpression");
}

return memberExpression.Member.Name;
}
}
}

有的人可能会问“PropertySupport”到底是干嘛的?其实我们经常写这样的代码:RaisePropertyChanged("SomeProperty"),这个代码本身没有任何问题,但是我们传入的是一个string,这也就暗示了两个小问题:1.当你的Property改名字以后,你需要修改这个string;2.输入string是个稍微容易出错的过程(打字错误)。那么PropertySupport.ExtractPropertyName便在牺牲了一点点效率的前提下,通过指定一个Expression来获得其属性的名字。所以我们就可以写成:RaisePropertyChanged(() = > PhoneNumber);如此一来,你只需要指定哪个属性即可,至于它的名字,不需要你操心,而且当下次你修改PhoneNumber为PrivatePhoneNumber后,你也不需要修改任何string。

Okay,既然我们说了要显示出一系列联系人,我们便需要一个View和ViewModel。在ViewModels下添加ContactMasterViewModel:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using MvvmTutorial.Infrastructure;
using MvvmTutorial.Models;

namespace MvvmTutorial.ViewModels
{
public class ContactMasterViewModel : ObservableObject
{
#region Fields

private bool _isLoaded;
private ObservableCollection<Contact > _items = new ObservableCollection<Contact >();

#endregion // Fields

#region Properties

public IEnumerable<Contact > Items
{
get
{
// If we load this view model in design mode (for example, in VS or Expression),
// we add some random data so that we can preview the layout of our view
if (DesignHelper.IsInDesignMode)
{
for (int i = 0; i < 25; ++i)
{
_items.Add(new Contact().GenerateRandomData());
}
}
else if (!_isLoaded)
{
Load();
}
return _items;
}
}

#endregion // Properties

#region Private Methods

private void Load()
{
// TODO: Once we finish the implementation of data persistence layer,
// we need to re-write this code to make this method work for real-world app.

// We haven't implemented data persistence
// Therefore, we temporarily load some random data in memory
for (int i = 0; i < 25; ++i)
{
_items.Add(new Contact().GenerateRandomData());
}
_isLoaded = true;
}

#endregion // Private Methods
}
}

注意这里面的DesignHelper:在Infrastructure下添加DesignHelper类:
分享到:
评论

相关推荐

    刘铁猛wpf MVVM教程所实现的demo和项目

    【标题】:“刘铁猛wpf MVVM教程所实现的demo和项目”是基于Windows Presentation Foundation(WPF)框架,采用Model-View-ViewModel(MVVM)设计模式的一个教学实践项目。刘铁猛,可能是一位知名的IT教育专家,通过...

    Silverlight的MVVM教程

    ### Silverlight的MVVM教程:理解与应用 #### 模型-视图-ViewModel (MVVM) 设计模式解析 **Silverlight MVVM教程**旨在深入探讨基于Silverlight的MVVM开发模式,这是一种广泛应用于现代用户界面开发的设计模式,...

    WPF教程MVVM模式实例

    **WPF教程MVVM模式实例** 本教程是针对初学者设计的一个使用Visual Studio 2010开发的WPF(Windows Presentation Foundation)应用程序实例,它深入介绍了MVVM(Model-View-ViewModel)设计模式。MVVM是一种流行的...

    基于MvvmLight的MVVM程序内附详细说明.7z

    一个 基于 MVVM LIGHT程序实例,内附详细的教程。包括1.1 MVVM Light Toolkit下载,安装 目录 1 MVVM Light的安装 1 1.1 MVVM Light Toolkit下载 1 1.2 MVVM Light Toolkit安装 2 2 程序实例 3 2.1 建立工程文件 3 ...

    MVVM入门与提高

    2. **消息总线**:如MVVM Light的EventAggregator,用于在不直接引用的情况下,实现ViewModel之间的通信。 3. **状态管理**:对于大型项目,可能需要一个全局的状态管理解决方案,如Redux或Flux。 4. **生活周期管理...

    WPF mvvm框架Stylet使用教程-窗体交互用法

    **WPF MVVM框架Stylet使用教程 - 窗体交互用法** Windows Presentation Foundation (WPF) 是Microsoft提供的一种用于构建桌面应用程序的框架,它引入了Model-View-ViewModel (MVVM) 设计模式,使得UI设计和业务逻辑...

    WPF使用MVVMLight框架写的Demo软件

    2. 在UserControl的XAML中设计UI。 3. 在UserControl的代码-behind中添加任何必要的逻辑。 4. 在主视图中引用并使用该用户控件。 **使用Messenger实现VM之间的通信** 在MVVM架构中,通常避免ViewModel直接相互引用...

    WPF与Silverlight的MVVM模式教程

    ### WPF与Silverlight的MVVM模式教程:深入解析与实战指南 #### 一、MVVM模式概览 MVVM(Model-View-ViewModel)模式是一种软件架构模式,旨在简化用户界面的开发过程,尤其在WPF(Windows Presentation ...

    mvvm享学项目代码资料

    2. View(视图):视图层是用户看到和交互的部分,包括UI元素、布局和事件处理。在MVVM架构中,视图与模型是解耦的,它不直接操作模型,而是通过数据绑定与ViewModel进行通信。 3. ViewModel(视图模型):视图模型...

    MVVM Light例程集合

    2. **GalaSoft.MvvmLight.Command**: 这是MVVMLight提供的命令实现,如RelayCommand和 RelayCommand,使得在ViewModel中可以轻松创建可执行操作的命令对象。 3. **Messenger**: Messenger是MVVMLight中的一个消息...

    mvvm的复杂的案例教程

    本教程针对初学者,将深入探讨如何在一个复杂的项目中实现MVVM,以帮助你更好地理解和应用这一模式。下面我们将详细讲解MVVM的核心概念、工作原理以及如何在实际项目中运用。 **MVVM简介** MVVM由微软的WPF团队提出...

    WPF_MVVM_入门教程_Quick Start Tutorial_文章和源码

    2. 查看 "WPF_MVVM_入门教程.docx",文档会详细介绍示例项目的设计和实现。 3. 打开示例项目的解决方案,查看各个类的结构和代码。 4. 运行示例程序,观察数据绑定和命令如何在实际应用中工作。 通过这个教程,你...

    MEF 结合 MVVMLight

    **在提供的压缩包文件“MVVMLight”中,可能包含了关于如何将MEF与MVVMLight结合使用的示例代码或者教程。通过研究这些示例,开发者可以更好地理解和学习这两个强大的框架如何协同工作,从而提升他们的应用程序开发...

    WPF MVVM 数据绑定

    在本教程中,我们将深入探讨如何设置一个基础的MVVM模式,并利用WPF的数据绑定特性。 首先,我们来理解MVVM模式的三个主要组件: 1. **Model(模型)**:这是你的应用的业务逻辑层,通常包含与数据库交互的实体类...

    WPF:如果Carlsberg做到了MVVM框架:n的第6部分

    2. **WPF与MVVM**:阐述WPF如何支持MVVM模式,如数据绑定、依赖属性、命令等特性如何简化MVVM实现。 3. **Cinch框架**:介绍Cinch框架的结构、主要组件和使用方法,展示如何利用Cinch快速搭建WPF MVVM项目。 4. **...

    刘铁锰MVVM代码示例

    2. WPF(Windows Presentation Foundation):WPF是.NET Framework的一部分,用于构建桌面应用程序。它提供了丰富的UI元素、数据绑定、依赖属性等特性,非常适合实现MVVM模式。 3. 数据绑定:在MVVM中,数据绑定是...

    深入浅出WPF-刘铁猛-MVVM视频源代码,MVVM入门与提高视频对应的源代码

    2. **视图(View)**:视图是用户看到和交互的部分,通常由WPF控件和布局构成。视图通过数据绑定与ViewModel进行通信,但并不直接操作Model。 3. **视图模型(ViewModel)**:作为视图和模型之间的桥梁,ViewModel...

    Avalonia 项目使用ReactiveUI实现的MVVM

    2. **命令(Commands)**:`ReactiveCommand`是ReactiveUI提供的一个命令实现,它可以监听一个可观察对象(通常是用户界面的事件)并执行相应的操作。这使得在ViewModel中处理按钮点击等交互事件变得简单。 3. **...

    WPF-MvvmLight

    2. ** GalaSoft.MvvmLight Messenger**: 一个消息传递系统,允许不同层之间进行松散耦合的通信,无需直接引用彼此。 3. ** GalaSoft.MvvmLight.Command**: 提供了基于委托的命令实现,使得在ViewModel中定义和执行...

    MVVM详细教程提高篇

    本教程将深入探讨MVVM模式的核心概念、实现方式以及在实际项目中的应用。 **1. 模型(Model)** 模型是业务逻辑和数据的载体,负责处理应用程序的数据和业务规则。它不直接与视图或视图模型交互,而是通过提供公共...

Global site tag (gtag.js) - Google Analytics