Intersoft ClientUI Documentation
Walkthrough: Display Data in GridPresenter using MVVM Pattern

This walkthrough shows you how to use MVVM pattern to display data using GridPresenter.

This walkthrough demonstrate the following concept:

Prerequisites

You need the following components to complete this walkthrough:

Creating a new ClientUI MVVM Application Project

The first step is to create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template in Visual Studio.

To create the ClientUI MVVM Application project

  1. Start Visual Studio 2010.
  2. Create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template. To learn more, see Walkthrough: Create New Intersoft ClientUI MVVM Application Template.
  3. In project reference, add System.Xml.Linq.dll. This assembly is required to perform LINQ query to xml data.

To add the data file

  1. In your project, create new folder with name Data.
  2. In Data folder, insert the data source from [Intersoft Installation Folder]\Intersoft WebUI Studio 2010 R1\Samples\SL4\ClientUI Samples\Intersoft.ClientUI.Samples.Assets\Data\ContactDataSource.xml.
  3. Click on the ContactDataSource.xml file and press F4 to open the Property Window. Change the Build Action property to Resources.

To add the resources file

  1. In your project, create new folder with name Assets.
  2. In Assets folder, create new folder with name Images.
  3. In Images folder, create new folder with name Photos.
  4. In Photos folder, copy the images from [Intersoft Installation Folder]\Intersoft WebUI Studio 2010 R1\Samples\SL4\ClientUI Samples\Intersoft.ClientUI.Samples.Assets\Images\Photos\].

Next, you will create the Contact model class that represent the data entity used in this walkthrough.

Creating Model Class

This section shows you how to create the Contact model class that represents the data entity used in this walkthrough. To create the Contact model class, see Walkthrough: Creating Model for Contact Data.

Next, you will create the view for your simple contacts list application.

Creating The View

This section steps you through the process of creating the user interface for your simple contacts list application using ClientUI controls such as GridPresenter.

To create the View pattern

  1. Add a GridPresenter. Set the following properties on the GridPresenter.
    Properties Value
    HorizantalAlignment Center
    VerticalAlignment Center
    RowHeight 128

    XAML
    Copy Code
    <Intersoft:UXPage 
            ...
        <Grid x:Name="LayoutRoot">
            <Intersoft:GridPresenter Name="gridPresenter1" RowHeight="128" HorizontalAlignment="Center" VerticalAlignment="Center" />
        </Grid>
    </Intersoft:UXPage>

  2. Create a new DataTemplate for with name RowTemplate and put it in Intersoft:UXPage.Resources.
    XAML
    Copy Code
    <Intersoft:UXPage.Resources>
        <DataTemplate x:Key="RowTemplate">
            <Grid Height="128">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Image HorizontalAlignment="Left" VerticalAlignment="Center"/>
                <Grid Grid.Column="1">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="24"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid Grid.RowSpan="5" HorizontalAlignment="Center" VerticalAlignment="Center">
                        <TextBlock FontSize="36" TextWrapping="NoWrap"/>
                    </Grid>
                    <TextBlock HorizontalAlignment="Left" FontSize="20" FontStyle="Italic" FontWeight="Normal" TextWrapping="NoWrap"/>
                    <TextBlock Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" TextWrapping="NoWrap"/>
                    <StackPanel Grid.Row="3" HorizontalAlignment="Right" VerticalAlignment="Bottom" Orientation="Horizontal">
                        <TextBlock Text="Phone : " TextWrapping="NoWrap"/>
                        <TextBlock TextWrapping="NoWrap"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" Grid.Row="5" HorizontalAlignment="Right">
                        <TextBlock Text="Cell : " TextWrapping="NoWrap"/>
                        <TextBlock TextWrapping="NoWrap"/>
                    </StackPanel>
                </Grid>
            </Grid>
        </DataTemplate>
    </Intersoft:UXPage.Resources>

Creating the ViewModel

This section steps you through the process of creating a ViewModel class that contains the properties to describe the View that you created in the previous section. The ViewModel defines the Contacts property to represent an observable collection of Contact.

To create the ViewModel

  1. Add a new class to the ViewModels folder in your Silverlight project and name it ContactViewModel.cs.
  2. Open the ContactViewModel.cs and inherit the class from ViewModelBase class.
    C#
    Copy Code
    public class ContactViewModel : ViewModelBase { }
  3. In this view mode, you add the Contacts which represent a collection of Contact.
    C#
    Copy Code
    // Views
    public ObservableCollection<Contact> Contacts { get; set; }
  4. Create a LoadData method to fill the Contact property based on the data from ContactDataSource.xml and invoke the method during object construction.
    C#
    Copy Code
    public ContactViewModel()
    {
        this.LoadContacts();
    }
    
    private void LoadContacts()
    {
        // loads contact data from xml file
        StreamResourceInfo resource = System.Windows.Application.GetResourceStream(
                new Uri("GridPresenterMVVM;component/Assets/Data/ContactDataSource.xml", UriKind.Relative));
    
        XDocument doc = XDocument.Load(resource.Stream);
    
        var contacts = from x in doc.Descendants("Customer")
                        select new Contact(x);
    
        this.Contacts = new ObservableCollection<Contact>();
    
        foreach (Contact contact in contacts)
        {
            contact.SetPhoto(this.Contacts.Count.ToString());
    
            this.Contacts.Add(contact);
        }
    
        resource.Stream.Close();
    }

Binding the View to the ViewModel

In the previous sections, you have learned how to create the Model and ViewModel classes, as well as the View that contains the user interface and controls used in this walkthrough. This section shows how to instantiate the ViewModel in the XAML page and bind the UI elements to the properties in the ViewModel such as the items source, data context and data template.

To bind the ViewModel pattern

  1. In Contacts.xaml, add the following mark up to instantiate ContactViewModel in Contact.xaml page.
    XAML
    Copy Code
    <Intersoft:UXPage.Resources>
        <ViewModels:ContactViewModel x:Key="ContactsData"/>
    </Intersoft:UXPage.Resources>
  2. Inside the Contact.xaml, locate the Grid under UXPage.
  3. Bind the DataContext property of the Grid to {StaticResource ContactsData}.
    UXPage1
    Copy Code
    <Grid x:Name="LayoutRoot" DataContext="{StaticResource ContactsData}">
        <Intersoft:GridPresenter Name="gridPresenter1" RowHeight="128" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
  4. In Contacts.xaml, locate the GridPresenter under Grid.
  5. Bind the ItemsSource and DataTemplate properties of the GridPresenter from the ViewModel through the provided properties, such as shown in the following example.
    XAML
    Copy Code
    <Grid x:Name="LayoutRoot" DataContext="{StaticResource ContactsData}">
        <Intersoft:GridPresenter Name="gridPresenter1" RowHeight="128" HorizontalAlignment="Center" VerticalAlignment="Center" ItemsSource="{Binding Path=Contacts}" RowTemplate="{StaticResource RowTemplate}" />
    </Grid>
  6. In Contacts.xaml, locate the DataTemplate inside UXPage.Resources.
  7. Bind the controls inside DataTemplate such as Image and TextBlock to specific properties from ContactViewModel such as shown in the following example.
    XAML
    Copy Code
    <Intersoft:UXPage.Resources>
        <ViewModels:ContactViewModel x:Key="ContactsData"/>
        <DataTemplate x:Key="RowTemplate">
            <Grid Height="128">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Image HorizontalAlignment="Left" VerticalAlignment="Center" Source="{Binding Photo}"/>
                <Grid Grid.Column="1">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="24"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid Grid.RowSpan="5" HorizontalAlignment="Center" VerticalAlignment="Center">
                        <TextBlock FontSize="36" Text="{Binding Website}" TextWrapping="NoWrap"/>
                    </Grid>
                    <TextBlock HorizontalAlignment="Left" FontSize="20" FontStyle="Italic" FontWeight="Normal" Text="{Binding Name}" TextWrapping="NoWrap"/>
                    <TextBlock Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Email}" TextWrapping="NoWrap"/>
                    <StackPanel Grid.Row="3" HorizontalAlignment="Right" VerticalAlignment="Bottom" Orientation="Horizontal">
                        <TextBlock Text="Phone : " TextWrapping="NoWrap"/>
                        <TextBlock Text="{Binding Phone}" TextWrapping="NoWrap"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" Grid.Row="5" HorizontalAlignment="Right">
                        <TextBlock Text="Cell : " TextWrapping="NoWrap"/>
                        <TextBlock Text="{Binding Cell}" TextWrapping="NoWrap"/>
                    </StackPanel>
                </Grid>
            </Grid>
        </DataTemplate>
    </Intersoft:UXPage.Resources>
  8. Run the project

Conclusion

In this walkthrough, you have learned how to create ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template, and create classes and page based on the MVVM pattern. You also learned how to bind GridPresenter to a collection of data and how to use RowTemplate to display the contact detail.

For more information about application development using MVVM pattern, see MVVM Pattern Overview.

Complete Code Listing

This section lists the complete code used in this walkthrough.

Contact.cs

C#
Copy Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using GridPresenterMVVM.ViewModels;
using System.ComponentModel;
using System.Xml.Linq;

namespace GridPresenterMVVM.Models
{
    public class Contact : ModelBase
    {        
        #region Constructors

        public Contact()
        {
        }

        public Contact(XElement x)
            : this()
        {
            this._id = x.Element("Id").Value.Trim();
            this._name = x.Element("Name").Value.Trim();
            this._email = x.Element("Email").Value.Trim();

            this._address = x.Element("Address").Value.Trim();
            this._state = x.Element("State").Value.Trim();
            this._zipCode = x.Element("ZipCode").Value.Trim();

            this._phone = x.Element("Phone").Value.Trim();
            this._fax = x.Element("Fax").Value.Trim();
            this._cell = x.Element("Cell").Value.Trim();

            this._blog = x.Element("Blog").Value.Trim();
            this._twitter = x.Element("Twitter").Value.Trim();
            this._website = x.Element("Website").Value.Trim();
        }

        #endregion

        #region Fields

        private string _name = string.Empty;
        private string _address = string.Empty;
        private string _phone = string.Empty;
        private string _cell = string.Empty;
        private string _id = string.Empty;
        private string _email = string.Empty;
        private string _fax = string.Empty;
        private string _blog = string.Empty;
        private string _twitter = string.Empty;
        private string _website = string.Empty;
        private string _state = string.Empty;
        private string _zipCode = string.Empty;
        private Uri _photo = null;

        #endregion

        #region Properties

        public string Name
        {
            get
            {
                return this._name;
            }

            set
            {
                if (this._name != value)
                {
                    this._name = value;
                    this.ClearError("Name");
                    this.OnPropertyChanged("Name");
                }
            }
        }

        public string Address
        {
            get
            {
                return this._address;
            }

            set
            {
                if (this._address != value)
                {
                    this._address = value;
                    this.ClearError("Address");
                    this.OnPropertyChanged("Address");
                }
            }
        }

        public string Phone
        {
            get
            {
                return this._phone;
            }

            set
            {
                if (this._phone != value)
                {
                    this._phone = value;
                    this.OnPropertyChanged("Phone");
                }
            }
        }

        public string Cell
        {
            get
            {
                return this._cell;
            }

            set
            {
                if (this._cell != value)
                {
                    this._cell = value;
                    this.OnPropertyChanged("Cell");
                }
            }
        }

        public string Id
        {
            get
            {
                return this._id;
            }

            set
            {
                if (this._id != value)
                {
                    this._id = value;
                    this.OnPropertyChanged("Id");
                }
            }
        }

        public string Email
        {
            get
            {
                return this._email;
            }

            set
            {
                if (this._email != value)
                {
                    this._email = value;
                    this.OnPropertyChanged("Email");
                }
            }
        }

        public string Fax
        {
            get
            {
                return this._fax;
            }

            set
            {
                if (this._fax != value)
                {
                    this._fax = value;
                    this.OnPropertyChanged("Fax");
                }
            }
        }

        public string Blog
        {
            get
            {
                return this._blog;
            }

            set
            {
                if (this._blog != value)
                {
                    this._blog = value;
                    this.OnPropertyChanged("Blog");
                }
            }
        }

        public string Twitter
        {
            get
            {
                return this._twitter;
            }

            set
            {
                if (this._twitter != value)
                {
                    this._twitter = value;
                    this.OnPropertyChanged("Twitter");
                }
            }
        }

        public string Website
        {
            get
            {
                return this._website;
            }

            set
            {
                if (this._website != value)
                {
                    this._website = value;
                    this.OnPropertyChanged("Website");
                }
            }
        }

        public string State
        {
            get
            {
                return this._state;
            }

            set
            {
                if (this._state != value)
                {
                    this._state = value;
                    this.OnPropertyChanged("State");
                }
            }
        }

        public string ZipCode
        {
            get
            {
                return this._zipCode;
            }

            set
            {
                if (this._zipCode != value)
                {
                    this._zipCode = value;
                    this.ClearError("ZipCode");
                    this.OnPropertyChanged("ZipCode");
                }
            }
        }

        public Uri Photo
        {
            get
            {
                return this._photo;
            }

            set
            {
                if (this._photo != value)
                {
                    this._photo = value;
                    this.OnPropertyChanged("Photo");
                }
            }

        }

        #endregion

        #region Methods

        public void SetPhoto(string uri)
        {
            this.Photo = new Uri("/Intersoft.ClientUI.Samples;component/Assets/Images/Photos/" + uri + ".jpg", UriKind.RelativeOrAbsolute);
        }  

        #endregion

    }
}

Contact.xaml

XAML
Copy Code
<Intersoft:UXPage 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:Intersoft="http://intersoft.clientui.com/schemas"
    xmlns:ViewModels="clr-namespace:GridPresenterMVVM.ViewModels"
        mc:Ignorable="d"
        x:Class="GridPresenterMVVM.Views.Contact" 
        Title="Contact Page"
        d:DesignWidth="640" d:DesignHeight="480">

    <Intersoft:UXPage.Resources>
        <ViewModels:ContactViewModel x:Key="ContactsData"/>
        <DataTemplate x:Key="RowTemplate">
            <Grid Height="128">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Image HorizontalAlignment="Left" VerticalAlignment="Center" Source="{Binding Photo}"/>
                <Grid Grid.Column="1">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="24"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid Grid.RowSpan="5" HorizontalAlignment="Center" VerticalAlignment="Center">
                        <TextBlock FontSize="36" Text="{Binding Website}" TextWrapping="NoWrap"/>
                    </Grid>
                    <TextBlock HorizontalAlignment="Left" FontSize="20" FontStyle="Italic" FontWeight="Normal" Text="{Binding Name}" TextWrapping="NoWrap"/>

                    <TextBlock Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Email}" TextWrapping="NoWrap"/>
                    <StackPanel Grid.Row="3" HorizontalAlignment="Right" VerticalAlignment="Bottom" Orientation="Horizontal">
                        <TextBlock Text="Phone : " TextWrapping="NoWrap"/>
                        <TextBlock Text="{Binding Phone}" TextWrapping="NoWrap"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" Grid.Row="5" HorizontalAlignment="Right">
                        <TextBlock Text="Cell : " TextWrapping="NoWrap"/>
                        <TextBlock Text="{Binding Cell}" TextWrapping="NoWrap"/>
                    </StackPanel>
                </Grid>
            </Grid>
        </DataTemplate>
    </Intersoft:UXPage.Resources>

    <Grid x:Name="LayoutRoot" DataContext="{StaticResource ContactsData}">
        <Intersoft:GridPresenter Name="gridPresenter1" RowHeight="128" HorizontalAlignment="Center" VerticalAlignment="Center" ItemsSource="{Binding Path=Contacts}" RowTemplate="{StaticResource RowTemplate}" />
    </Grid>
</Intersoft:UXPage>

ContactViewModel.cs

C#
Copy Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Intersoft.Client.Framework.Input;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Resources;
using System.Xml.Linq;
using GridPresenterMVVM.Models;

namespace GridPresenterMVVM.ViewModels
{
    public class ContactViewModel : ViewModelBase
    {
        // Views
        public ObservableCollection<Contact> Contacts { get; set; }

        public string ContactsCount
        {
            get
            {
                if (this.Contacts.Count == 0)
                    return "No contacts";
                else if (this.Contacts.Count == 1)
                    return "1 contact";
                else
                    return this.Contacts.Count + " contacts";
            }
        }

        public ContactViewModel()
        {
            this.LoadContacts();
        }

        private void LoadContacts()
        {
            // loads contact data from xml file
            StreamResourceInfo resource = System.Windows.Application.GetResourceStream(
                    new Uri("GridPresenterMVVM;component/Assets/Data/ContactDataSource.xml", UriKind.Relative));

            XDocument doc = XDocument.Load(resource.Stream);

            var contacts = from x in doc.Descendants("Customer")
                           select new Contact(x);

            this.Contacts = new ObservableCollection<Contact>();

            foreach (Contact contact in contacts)
            {
                contact.SetPhoto(this.Contacts.Count.ToString());

                this.Contacts.Add(contact);
            }

            resource.Stream.Close();
        }

        protected virtual void InvalidateCommands()
        {
        }
    }
}
See Also

Concepts

Other Resources