Intersoft ClientUI Documentation
Walkthrough: Display Data Details of UXFlow’s SelectedItem using MVVM Pattern

This walkthrough shows you how to use MVVM pattern to show detailed info for the selected item of UXFlow.

In this walkthrough, you perform the following tasks:

Prerequisites

You need the following components to complete this walkthrough:

Creating a new ClientUI MVVM Project

The first step is to create a new ClientUI MVVM Application using Intersoft ClientUI MVVM 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 a 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\HotelDataSource.xml.
  3. Click on the HotelDataSource.xml file and press F4 to open the Property Window. Change the BuildAction property to Resources.

To add the resources file

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

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

Creating Model Class

This section shows you how to create the Hotel model class that represents the data entity used in this walkthrough. The Hotel model class contains constructors to obtain the URI path of the hotel's image.

To create the Hotel Model class

  1. Create a Model class that inherits ModelBase class under the Models folder. You can name it Hotel.cs.
  2. Add Image property to the Hotel model class by defining the backing field with complete getter and setter in the property. In the setter property you will need to call OnPropertyChanged method after the backing field is assigned to the new value.
    Sample Code
    Copy Code
    private Uri _image;
            
    public Uri Image
    {
        get
        {
            return this._image;
        }
    
        set
        {
            if (this._image != value)
            {
                this._image = value;
                this.OnPropertyChanged("Image");
            }
        }
    }
  3. Also add Location and Name property to the Hotel model class by repeating step number 2.
    Sample Code
    Copy Code
    public class Hotel : ViewModels.ModelBase
    {
        #region Fields
    
        private Uri _image;
        private string _location;
        private string _name;
    
        #endregion
    
        #region Properties
    
        public Uri Image
        {
            get
            {
                return this._image;
            }
    
            set
            {
                if (this._image != value)
                {
                    this._image = value;
                    this.OnPropertyChanged("Image");
                }
            }
        }
    
        public string Location
        {
            get
            {
                return this._location;
            }
    
            set
            {
                if (this._location != value)
                {
                    this._location = value;
                    this.OnPropertyChanged("Location");
                }
            }
        }
    
        public string Name
        {
            get
            {
                return this._name;
            }
    
            set
            {
                if (this._name != value)
                {
                    this._name = value;
                    this.OnPropertyChanged("Name");
                }
            }
        }
    
        #endregion
    }
  4. Add constructor of the Hotel class.
    Sample Code
    Copy Code
    public Hotel()
    {
    
    }
    
    public Hotel(XElement h)
        : this()
    {
        string image = h.Element("Image").Value.Trim();
        this._image = new Uri("/UXListBox-Walkthrough;component/Images/" + image, UriKind.RelativeOrAbsolute);
        this._location = h.Element("Location").Value.Trim();
        this._name = h.Element("Name").Value.Trim();
    }

Creating the View

This section show how to create a View used in the application interface. You will bind the data to the control in the later section.

To create the HotelList page

  1. Add a new UXPage to the Views folder in your Silverlight project and name it HotelList.xaml
    For more information on how to add a new item in Visual Studio, see Walkthrough: Add New Item such as Page, Dialog Box and Window in VS 2010
  2. Open the newly created HotelList.xaml page and clear the content inside the LayoutRoot.
  3. Add a DockPanel.
    Set the Height and Width property into Auto
  4. Add a UXFlow inside the DockPanel. Click on the Right section of the docking visual hint to dock the UXFlow to the right and click the Fill section of the docking visual hint to fill the UXFlow at the entire DockPanel. Set the Width property to Auto.
    XAML
    Copy Code
    <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
        <Intersoft:UXFlow Height="480" Name="uXFlow1" Intersoft:DockPanel.Dock="Right" Intersoft:DockPanel.IsFillElement="True"></Intersoft:UXFlow>
    </Intersoft:DockPanel>

  5. Add a DockPanel inside the previous DockPanel. Set the following properties on the second DockPanel.
    Properties Value
    HorizontalAlignment Center
    VerticalAlignment Center
    DockPanel.Dock Left
    Height Auto

    XAML
    Copy Code
    <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
        ...
        <Intersoft:DockPanel Name="dockPanel2" Width="200" Intersoft:DockPanel.Dock="Left" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Intersoft:DockPanel>

  6. Add a GlassLabel inside the second DockPanel. Set the following properties on the GlassLabel.
    Properties Value
    DockPanel.Dock Top
    Width 200
    Content Reset Value
     
  7. Add a StackPanel inside the GlassLabel. Set the Height and Width property into Auto
  8. Add a TextBlock. Set the HorizantalAlignment property to Center and FontSize property to 14
  9. Repeat point number 6 once. Set the HorizantalAlignment property to Center and FontSize property to 11
  10. Add a FieldLabel, put it inside the second DockPanel. Set the following properties on the first FieldLabel.
    Properties Value
    DockPanel.Dock Top
    HorizontalAlignment Left
    Header Rating:
     
  11. Repeat point number 8 once. Set the following properties on the second FieldLabel.
    Properties Value
    DockPanel.Dock Top
    HorizontalAlignment Left
    Header Rate:

    XAML
    Copy Code
    <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
        <Intersoft:UXFlow Height="480" Name="uXFlow1" Intersoft:DockPanel.Dock="Right" Intersoft:DockPanel.IsFillElement="True"></Intersoft:UXFlow>
        <Intersoft:DockPanel Name="dockPanel2" Width="200" Intersoft:DockPanel.Dock="Left" HorizontalAlignment="Center" VerticalAlignment="Center" Intersoft:DockPanel.IsFillElement="True">
            <Intersoft:GlassLabel Name="glassLabel1" Intersoft:DockPanel.Dock="Top" Width="200">
                <StackPanel Name="stackPanel1">
                    <TextBlock Name="textBlock1" Text="TextBlock" HorizontalAlignment="Center" />
                    <TextBlock Name="textBlock2" Text="TextBlock" HorizontalAlignment="Center" />
                </StackPanel>
            </Intersoft:GlassLabel>
            <Intersoft:FieldLabel Header="Rating: " Name="fieldLabel1" Intersoft:DockPanel.Dock="Top" HorizontalAlignment="Left">
                <Intersoft:UXTextBox HorizontalAlignment="Left" Name="uXTextBox1" Text="UXTextBlock" VerticalAlignment="Top" />
            </Intersoft:FieldLabel>
            <Intersoft:FieldLabel Header="Rate: " Name="fieldLabel2" Intersoft:DockPanel.Dock="Top" HorizontalAlignment="Left">
                <Intersoft:UXTextBox HorizontalAlignment="Left" Name="uXTextBox2" Text="UXTextBlock" VerticalAlignment="Top" />
            </Intersoft:FieldLabel>
        </Intersoft:DockPanel>
    </Intersoft:DockPanel>

  12. When run the project, The looks of the Views should be like down below.

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 Hotels collection to represent an observable collection of Hotel model and a LoadData method to load hotel data from xml file.

To create the HotelListViewModel

  1. Add a new class to the ViewModels folder in your Silverlight project and name it HotelListViewModel.cs.
  2. Open HotelListViewModel.cs and inherit the class from ViewModelBase class.
    Sample Code
    Copy Code
    public class HotelListViewModel : ViewModelBase
  3. In this view mode, you add the Hotels properties which represent a collection of Hotel model. You also add SelectedItem such with type Hotel that will be bound to the SelectedItem property of UXFlow in the view, such as shown in the following code listing.
    Sample Code
    Copy Code
    public class HotelListViewModel : ViewModelBase
    {
        // Fields
        private Hotel _selectedItem = null;
    
        // Views
        public ObservableCollection<Hotel> Hotels { get; set; }
    
    
        // Selection, View States
        public Hotel SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                if (_selectedItem != value)
                {
                    _selectedItem = value;
                    OnPropertyChanged("SelectedItem");
                }
            }
        }
    
        // Constructor
        public HotelListViewModel()
        {
            this.LoadData();
        }
    
        private void LoadData()
        {
            // loads hotel data from xml file
            StreamResourceInfo resource = System.Windows.Application.GetResourceStream(
                    new Uri("UXListBox-Walkthrough;component/Data/HotelDataSource.xml", UriKind.Relative));
            XDocument doc = XDocument.Load(resource.Stream);
    
            var hotels = from x in doc.Descendants("Hotel")
                            select new Hotel(x);
    
            this.Hotels = new ObservableCollection<Hotel>();
    
            foreach (Hotel hotel in hotels)
            {
                this.Hotels.Add(hotel);
            }
    
            resource.Stream.Close();
        }
    }

Next, you will bind the HotelListViewModel to your HotelList.xaml.

Binding the ViewModel to View

This section shows how to bind the ViewModel that was created in the previous section to the View, for example you will bind the ItemsSource of UXFlow to Hotels property of the HotelListViewModel.

To bind the ViewModel to HotelList.xaml

  1. Declare the namespace that maps to the HotelListViewModel class in the HotelList page. .
    XAML
    Copy Code
    <Intersoft:UXPage ... >
        ...
        <Intersoft:UXPage.DataContext>
            <ViewModels:HotelListViewModel />
        </Intersoft:UXPage.DataContext>
        ...
    </Intersoft:UXPage>
  2. In the UXFlow properties window.
    Locate the ItemsSource property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding options...
    3. From the Tab Path, select Hotels
    Locate the SelectedItem property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding pptions...
    3. From the Tab Path, select SelectedItem
    4. From the Tab Options, set Mode to TwoWay
    Locate the Binding tab property. Set the following properties.
    Properties Value
    ImageMemberPath Image
    SubTitleMemberPath Location
    TitleMemberPath Name

    XAML
    Copy Code
    <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom" DataContext="{Binding}">
        <Intersoft:UXFlow Height="480" Name="uXFlow1" Intersoft:DockPanel.Dock="Right" Intersoft:DockPanel.IsFillElement="True" ItemsSource="{Binding Path=Hotels, Mode=TwoWay}" SelectedItem="{Binding Path=SelectedItem}" ImageMemberPath="Image" SubTitleMemberPath="Location" TitleMemberPath="Name"></Intersoft:UXFlow>
        ...
    </Intersoft:DockPanel>
  3. Locate dockPanel2, then open properties window.
    Locate the DataContext property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding options...
    3. From the Tab Path, select SelectedItem 

    XAML
    Copy Code
    <Intersoft:DockPanel Name="dockPanel2" Width="200" Intersoft:DockPanel.Dock="Left" HorizontalAlignment="Center" VerticalAlignment="Center" DataContext="{Binding Path=SelectedItem}">
        <Intersoft:GlassLabel Name="glassLabel1" Intersoft:DockPanel.Dock="Top" Width="200">
        ...
    </Intersoft:DockPanel>
  4. Locate textBlock1, then open properties window.
    Locate the Text property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding options...
    3. From the Tab Path, select Name

    XAML
    Copy Code
    <StackPanel Name="stackPanel1">
        <TextBlock Name="textBlock1" Text="{Binding Path=Name}" HorizontalAlignment="Center"/>
        ...
    </StackPanel>
  5. Locate textBlock2, then open properties window.
    Locate the Text property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding options...
    3. From the Tab Path, select Location

    XAML
    Copy Code
    <StackPanel Name="stackPanel1">
        ...
        <TextBlock Name="textBlock2" Text="{Binding Path=Location}" HorizontalAlignment="Center"/>
    </StackPanel>
  6. Locate uXTextBox1, then open properties window.
    Locate the Text property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding options...
    3. From the Tab Path, select Rating

    XAML
    Copy Code
    <Intersoft:FieldLabel Header="Rating: " ... >
        <Intersoft:UXTextBox HorizontalAlignment="Left" Name="uXTextBox1" Text="{Binding Path=Rating}" VerticalAlignment="Top" />
    </Intersoft:FieldLabel>
  7. Locate uXTextBox2, then properties window.
    Locate the Text property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding options...
    3. From the Tab Path, select Rate
    XAML
    Copy Code
    <Intersoft:FieldLabel Header="Rate: " ... >
        <Intersoft:UXTextBox HorizontalAlignment="Left" Name="uXTextBox2" Text="{Binding Path=Rate}" VerticalAlignment="Top" />
    </Intersoft:FieldLabel>

  8. This will be the final looks of Cover Flow.

Complete Code Listing

This section lists the complete code used in this walkthrough.

Hotel.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 System.Xml.Linq;
using CoverFlowMVVM.ViewModels;

namespace CoverFlowMVVM.Models
{
    public class Hotel: ModelBase
    {
        #region Constructors

        public Hotel(XElement h)
        {
            string image = h.Element("Image").Value.Trim();
            this._image = new Uri("/CoverFlowMVVM;component/Assets/Images/" + image, UriKind.RelativeOrAbsolute);
            this._location = h.Element("Location").Value.Trim();
            this._name = h.Element("Name").Value.Trim();
            this._rate = h.Element("Rate").Value.Trim();
            this._rating = h.Element("Rating").Value.Trim();
        }

        #endregion

        #region Fields

        private Uri _image;
        private string _location;
        private string _name;
        private string _rate;
        private string _rating;

        #endregion

        #region Properties

        public Uri Image
        {
            get
            {
                return this._image;
            }

            set
            {
                if (this._image != value)
                {
                    this._image = value;
                    this.OnPropertyChanged("Image");
                }
            }
        }

        public string Location
        {
            get
            {
                return this._location;
            }

            set
            {
                if (this._location != value)
                {
                    this._location = value;
                    this.OnPropertyChanged("Location");
                }
            }
        }

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

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

        public string Rate
        {
            get
            {
                return this._rate;
            }

            set
            {
                if (this._rate != value)
                {
                    this._rate = value;
                    this.OnPropertyChanged("Rate");
                }
            }
        }

        public string Rating
        {
            get
            {
                return this._rating;
            }

            set
            {
                if (this._rating != value)
                {
                    this._rating = value;
                    this.OnPropertyChanged("Rating");
                }
            }
        }

        #endregion
    }
}

HotelList.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:CoverFlowMVVM.ViewModels"
        mc:Ignorable="d"
        x:Class="CoverFlowMVVM.Views.HotelList" 
        Title="HotelList Page"
        d:DesignWidth="640" d:DesignHeight="480">

    <Intersoft:UXPage.DataContext>
        <ViewModels:HotelListViewModel />
    </Intersoft:UXPage.DataContext>

    <Grid x:Name="LayoutRoot">
        <Intersoft:DockPanel Name="dockPanel1" FillChildMode="Custom">
            <Intersoft:UXFlow Height="480" Name="uXFlow1" Intersoft:DockPanel.Dock="Right" Intersoft:DockPanel.IsFillElement="True" ItemsSource="{Binding Path=Hotels, Mode=TwoWay}" ImageMemberPath="Image" SubTitleMemberPath="Location" TitleMemberPath="Name" SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}"></Intersoft:UXFlow>
            <Intersoft:DockPanel Name="dockPanel2" Width="200" Intersoft:DockPanel.Dock="Left" HorizontalAlignment="Center" VerticalAlignment="Center" DataContext="{Binding Path=SelectedItem}" Intersoft:DockPanel.IsFillElement="True">
                <Intersoft:GlassLabel Name="glassLabel1" Intersoft:DockPanel.Dock="Top" Width="200">
                    <StackPanel Name="stackPanel1">
                        <TextBlock Name="textBlock1" Text="{Binding Path=Name}" HorizontalAlignment="Center" />
                        <TextBlock Name="textBlock2" Text="{Binding Path=Location}" HorizontalAlignment="Center" />
                    </StackPanel>
                </Intersoft:GlassLabel>
                <Intersoft:FieldLabel Header="Rating: " Name="fieldLabel1" Intersoft:DockPanel.Dock="Top" HorizontalAlignment="Left">
                    <Intersoft:UXTextBox HorizontalAlignment="Left" Name="uXTextBox1" Text="{Binding Path=Rating}" VerticalAlignment="Top" />
                </Intersoft:FieldLabel>
                <Intersoft:FieldLabel Header="Rate: " Name="fieldLabel2" Intersoft:DockPanel.Dock="Top" HorizontalAlignment="Left">
                    <Intersoft:UXTextBox HorizontalAlignment="Left" Name="uXTextBox2" Text="{Binding Path=Rate}" VerticalAlignment="Top" />
                </Intersoft:FieldLabel>
            </Intersoft:DockPanel>
        </Intersoft:DockPanel>
    </Grid>
</Intersoft:UXPage>

HotelListViewModel.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 CoverFlowMVVM.Models;
using System.Windows.Resources;
using System.Xml.Linq;
using System.Linq;

namespace CoverFlowMVVM.ViewModels
{
    public class HotelListViewModel : ViewModelBase
        {
            // Fields
            private Hotel _selectedItem = null;

            // Views
            public ObservableCollection<Hotel> Hotels { get; set; }


            // Selection, View States
            public Hotel SelectedItem
            {
                get { return _selectedItem; }
                set
                {
                    if (_selectedItem != value)
                    {
                        _selectedItem = value;
                        OnPropertyChanged("SelectedItem");
                    }
                }
            }

            // Constructor
            public HotelListViewModel()
            {
                this.LoadData();
            }

            private void LoadData()
            {
                // loads hotel data from xml file
                StreamResourceInfo resource = System.Windows.Application.GetResourceStream(
                        new Uri("UXListBox-Walkthrough;component/Data/HotelDataSource.xml", UriKind.Relative));
                XDocument doc = XDocument.Load(resource.Stream);

                var hotels = from x in doc.Descendants("Hotel")
                                select new Hotel(x);

                this.Hotels = new ObservableCollection<Hotel>();

                foreach (Hotel hotel in hotels)
                {
                    this.Hotels.Add(hotel);
                }

                resource.Stream.Close();
            }
        }
}
See Also

Concepts

Other Resources