Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / IIS

WCF by Example - Chapter VI - WPF Client - Baseline

4.93/5 (14 votes)
23 Oct 2012CPOL4 min read 63.1K  
Baseline WCF Client application using the MVVM pattern
PreviousNext
Chapter VChapter VII

The Series

WCF by example is a series of articles that describe how to design and develop a WPF client using WCF for communication and NHibernate for persistence purposes. The series introduction describes the scope of the articles and discusses the architect solution at a high level.

Sharpy - A Metro Project

23 Oct: I am currently working on a new project for a Metro application: Sharpy. I intend to use the patterns discussed in WCF by Example for the service side of the application; the goal is to demonstrate how similar is the development of Metro applications to the type of applications we have seen so far. There is not code available yet but hopefully this will change soon. I hope you like it. The article is in here.

Chapter Overview

In the previous chapters, we have discussed the design and implementation of the core server components. At this time, we are ready for setting up a client to interact with our services and business logic at the server side.

As we indicated at the start of the series, our rich client is based on WPF using the MVVM pattern. It is assumed that the reader is familiar with the basic concepts of WPF and the MVVM.

The source code for this chapter can be found at Codeplex change set 73737. The latest code for the eDirectory solution is found at Codeplex.

Before We Start

The main principle used in the design of the rich client is that the model should contain as much information as possible and using the XAML binding capabilities so very little code is created in the view. The ViewModel will be responsible for the creation of views and the retrieval of model instances that are bound directly to the view.

As a result of this approach, the design uses extensively the operation pattern (RelayCommand) on the model to invoke methods defined in the ViewModel, on the view the dependency properties in XAML are used as a way for extending the binding capabilities between the model and view. Also converters are useful in this approach for the command execution. In a later chapter, we will demonstrate the use of the INotifyPropertyChange pattern in the ViewModel so both the model and view can notify each other when bound properties are changed.

As usual, for the view design we are again keeping things extremely simple. We are going to use the WPFToolkit as it provides a nice and comprehensive grid but for most of the time the view design just consists of writing XAML code.

WPFClient Project

This chapter introduces a new project in our eDirectory solution: eDirectory.WPF. The WPF project in this chapter consists of a single screen that provides users to create and visualize customer entities. Following the MVVM pattern, three files are created under the customer folder for the View (XAML), Model (DTOs) and ViewModel.

Image 3

The Model

The model is very simple, we are just re-using the DTOs that were already defined in the common assembly. In this way, it is very simple to retrieve data from the services and re-used in a easy manner.

Operations are just DTO instances used to send information to services to the server, bindings are normally used to populate these instances so very little code is required when commands are executed when calling server services.

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

The View

Following is an extract of the XAML class:

XML
<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>

The following screen is generated from the above XAML:

Image 4

It is worth noting that in the grid definition, some properties are disabled so we have explicitly to declare the columns to display and their bindings.

Image 5

The ViewModel

The ViewModel responsibility is to create an instance of the view and retrieve the model using calls to the server services. At this point, the implementation of the ViewModel is simple:

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

    public CustomerModel Model { get; set; }
}

Couple aspects to notice in the above code are:

  • In this implementation, the constructor of the ViewModel creates an instance of the view and displays in a dialog mode.
  • The data context of the view is set to the ViewModel class which permits the View binding to any public property in the ViewModel using XAML.

The BootStrapper

In a traditional WPF application, a view is set as the start-up object, in our application this is not the case. We need a little more flexibility so we will create a BootStrapper method in the App.xaml.cs file that creates an instance of a specialized BootStrapper class and then creates an instance of CustomerViewModel.

Currently the eDirectoryBootStrapper class has no implementation, but it will be used in a later chapter when we cover dependency injection.

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

Chapter Summary

In this chapter, we have created a basic WPF client. Currently, it cannot execute server methods but we have established the baseline where the view and the model are bound using XAML bindings. We also defined the ViewModel and we indicated how it leverages the creation of views and binding of the model to the view.

In the next chapter, we will introduce the concept of the contract locator which provides the mechanism of executing service calls in a decoupled fashion. In later chapters, we will cover the RelayCommandService and the notify property changed pattern.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)