65.9K
CodeProject 正在变化。 阅读更多。
Home

WCF 示例 – 第六章 – WPF 客户端 – 基线

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (14投票s)

2010年7月27日

CPOL

4分钟阅读

viewsIcon

63979

使用 MVVM 模式的基线 WCF 客户端应用程序

Previous Next
第 V 章 第 VII 章

系列文章

WCF 示例是一系列文章,介绍了如何设计和开发使用 WCF 进行通信和 NHibernate 进行持久化的 WPF 客户端。该系列介绍描述了文章的范围,并从高层次讨论了架构解决方案。

Sharpy - 一个 Metro 项目

10 月 23 日:我目前正在进行一个 Metro 应用程序的新项目:Sharpy。我打算在应用程序的服务端使用 WCF 示例中讨论的模式;目标是展示 Metro 应用程序的开发与我们迄今为止所见的应用程序类型有多么相似。目前还没有代码,但希望很快就会有。希望您喜欢。文章在这里

章节概述

在前几章中,我们讨论了核心服务器组件的设计和实现。现在,我们可以开始设置一个客户端来与服务器端的服务和业务逻辑进行交互。

正如我们在系列开始时所指出的,我们的富客户端基于 WPF,并使用 MVVM 模式。假定读者熟悉 WPF 和 MVVM 的基本概念。

本章的源代码可以在Codeplex 更改集 73737 中找到。eDirectory 解决方案的最新代码可以在Codeplex 中找到。

开始之前

富客户端设计所用的主要原则是,模型应包含尽可能多的信息,并利用 XAML 的绑定功能,从而在视图中生成的代码非常少。ViewModel 将负责创建视图以及检索直接绑定到视图的模型实例。

因此,该设计广泛使用了模型上的操作模式(RelayCommand)来调用 ViewModel 中定义的方法,在视图中,XAML 中的依赖属性被用作扩展模型和视图之间绑定功能的一种方式。转换器在这种方法中对于命令执行也很有用。在后续章节中,我们将演示在 ViewModel 中使用 INotifyPropertyChange 模式,以便模型和视图在绑定属性更改时可以相互通知。

一如既往,对于视图设计,我们再次保持事物极其简单。我们将使用 WPFToolkit,因为它提供了漂亮且全面的网格,但大多数时候,视图设计仅由编写 XAML 代码组成。

WPFClient 项目

本章在我们的 eDirectory 解决方案中引入了一个新项目:eDirectory.WPF。本章中的 WPF 项目包含一个屏幕,允许用户创建和可视化客户实体。遵循 MVVM 模式,在 customer 文件夹下创建了三个文件,分别用于视图(XAML)、模型(DTOs)和 ViewModel。

模型

模型非常简单,我们只是重用了在通用程序集中已定义的 DTO。这样,从服务检索数据并以一种简单的方式重用它们就非常方便了。

操作只是用于将信息发送到服务器服务的 DTO 实例,绑定通常用于填充这些实例,因此在调用服务器服务执行命令时所需的代码非常少。

public class CustomerModel
{
    public CustomerDto NewCustomerOperation { get; set; }
    public IList<CustomerDto> CustomerList { get; set; }
}

View

以下是 XAML 类的一个摘录

<Window x:Class="eDirectory.WPF.Customer.View.CustomerView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"        
        Title="Customer View" Height="400" Width="400" 
		WindowStartupLocation="CenterScreen">
    <Grid Name="MainLayout">
        ... 
        <GroupBox Header="New Customer" Margin="5" Padding="5" Grid.Row="0">
            <Grid Name="NewCustomer">
            ...                
                <Label Grid.Column="0" Grid.Row="0">First Name</Label>
                <TextBox Grid.Column="0" Grid.Row="1" Text="{Binding Path=
		Model.NewCustomerOperation.FirstName, Mode=TwoWay}"></TextBox>
                ...
            </Grid>
        </GroupBox>
        <GroupBox Header="List of Customers" Margin ="5" Padding="5" Grid.Row="1">
            <Grid Name="ListOfCustomers">
                ...
                <tk:DataGrid Grid.Row="0" ... 
		ItemsSource="{Binding Path=Model.CustomerList}">                    
                    <tk:DataGrid.Columns>
                        <tk:DataGridTextColumn Header="Customer Id" 
			Binding="{Binding Path=CustomerId, Mode=OneWay}"/>
                        ...
                    </tk:DataGrid.Columns>
                </tk:DataGrid>
                ...
            </Grid>
        </GroupBox>
    </Grid>
</Window>

以下屏幕由上面的 XAML 生成

值得注意的是,在网格定义中,某些属性被禁用,因此我们需要显式声明要显示的列及其绑定。

ViewModel

ViewModel 的职责是创建视图的实例,并通过调用服务器服务来检索模型。此时,ViewModel 的实现很简单

public class CustomerViewModel
{
    private readonly CustomerView View;
        
    public CustomerViewModel()
    {
        View = new CustomerView();
        View.DataContext = this;
        View.ShowDialog();
    }

    public CustomerModel Model { get; set; }
}

上面代码中需要注意的几个方面是

  • 在此实现中,ViewModel 的构造函数创建视图的实例,并在对话框模式下显示它。
  • 视图的数据上下文被设置为 ViewModel 类,这允许视图使用 XAML 将任何 public 属性绑定到 ViewModel

引导程序

在传统的 WPF 应用程序中,视图被设置为启动对象,在我们的应用程序中情况并非如此。我们需要更多的灵活性,因此我们将在 App.xaml.cs 文件中创建一个 BootStrapper 方法,该方法创建一个专用 BootStrapper 类的实例,然后创建一个 CustomerViewModel 实例。

目前 eDirectoryBootStrapper 类没有实现,但在我们后续介绍依赖注入的章节中将会用到它。

public partial class App : Application
{
    private void BootStrapper
    (object sender, StartupEventArgs e)
    {
        var boot = new eDirectoryBootStrapper();
        boot.Run();
        new CustomerViewModel();
    }
}

章节总结

在本章中,我们创建了一个基本的 WPF 客户端。目前,它还不能执行服务器方法,但我们已经建立了视图和模型通过 XAML 绑定进行绑定的基线。我们还定义了 ViewModel,并指出了它如何利用视图的创建和模型的视图绑定。

在下一章中,我们将介绍合约定位器(contract locator)的概念,它提供了以解耦方式执行服务调用的机制。在后续章节中,我们将介绍 RelayCommandService 和属性更改通知模式。

© . All rights reserved.