Intersoft ClientUI 8 > ClientUI Fundamentals > MVVM Pattern Overview > MVVM Pattern Walkthroughs > Walkthrough: Displaying Item Detail using Rich User Interface Controls with MVVM Pattern |
This walkthrough shows you how to displaying item detail using rich user interface controls with MVVM pattern.
In this walkthrough, you perform the following tasks:
You need the following components to complete this walkthrough:
The first step is to create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template in Visual Studio.
This section shows how to create the Hotel model class that represents the data entity used in this walkthrough. The Hotel model class contains constructors to easily parse data from XML.
C# |
Copy Code
|
---|---|
private string _name; public string Name { get { return this._name; } set { if (this._name != value) { this._name = value; OnPropertyChanged("Name"); } } } |
C# |
Copy Code
|
---|---|
private string _name; private string _location; private string _rating; private string _rate; private string _image; public string Name { get { return this._name; } set { if (this._name != value) { this._name = value; OnPropertyChanged("Name"); } } } public string Location { get { return this._location; } set { if (this._location != value) { this._location = value; OnPropertyChanged("Location"); } } } public string Rating { get { return this._rating; } set { if (this._rating != value) { this._rating = value; OnPropertyChanged("Rating"); } } } public string Rate { get { return this._rate; } set { if (this._rate != value) { this._rate = value; OnPropertyChanged("Rate"); } } } public string Image { get { return this._image; } set { if (this._image != value) { this._image = value; OnPropertyChanged("Image"); } } } |
C# |
Copy Code
|
---|---|
using System.Xml.Linq; public class Hotel : ModelBase { ... public Hotel(XElement x) { this._name = x.Element("Name").Value.Trim(); this._location = x.Element("Location").Value.Trim(); this._rating = x.Element("Rating").Value.Trim(); this._rate = x.Element("Rate").Value.Trim(); this._image = x.Element("Image").Value.Trim(); } } |
This section steps you through the process of creating a page that uses a variety of ClientUI controls such as UXListBox, CallOut, UXScroller and GlassLabel. The UXListBox is used to display a collection of hotel data and when selected it will change CallOut data context to display selected hotel data.
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 |
Property | Value |
---|---|
Name | HotelCallOut |
Visibility | Visible |
Intersoft:DockPanel.IsFillElement | True |
StrokeThickness | 0 |
CornerRadius | 10 |
PointerPosition | Left |
PointerPoint1 | 12, 0 |
PointerPoint2 | 0,20 |
PointerPoint3 | -12, 0 |
Margin | 0 20 20 20 |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot" Background="{x:Null}" Width="640" Height="480" DataContext="{StaticResource vwHotel}"> <Border CornerRadius="20"> <Border.Background> <LinearGradientBrush> <GradientStopCollection> <GradientStop Color="Gray" Offset="0.5" /> <GradientStop Color="LightGray" Offset="1" /> </GradientStopCollection> </LinearGradientBrush> </Border.Background> <Border.Effect> <DropShadowEffect Color="Gray" /> </Border.Effect> <Intersoft:DockPanel FillChildMode="Custom"> <Intersoft:GlassLabel Content="Hotel" Intersoft:DockPanel.Dock="Top" SpreadBackground="Gray" /> <Intersoft:UXScroller Intersoft:DockPanel.Dock="Left" Margin="10 10 0 10"> <Intersoft:UXListBox Name="HotelList" Background="Black" /> </Intersoft:UXScroller> <Intersoft:CallOut Name="HotelCallOut" Visibility="Visible" Intersoft:DockPanel.IsFillElement="True" StrokeThickness="0" CornerRadius="10" Grid.Column="1" PointerPosition="Left" PointerPoint1="12, 0" PointerPoint2="0,20" PointerPoint3="-12, 0" Margin="0 20 20 20"> <Intersoft:CallOut.Background> <ImageBrush Stretch="UniformToFill" /> </Intersoft:CallOut.Background> </Intersoft:CallOut> </Intersoft:DockPanel> </Border> </Grid> |
XAML |
Copy Code
|
---|---|
<Intersoft:CallOut... > <Intersoft:CallOut.Background> ... </Intersoft:CallOut.Background> <Border VerticalAlignment="Bottom"> </Border> </Intersoft:CallOut> |
XAML |
Copy Code
|
---|---|
<Border... > <StackPanel VerticalAlignment="Center" Margin="40,0,0,0"> </StackPanel> </Border> |
XAML |
Copy Code
|
---|---|
<Border... > <StackPanel... > <TextBlock Foreground="White" FontSize="26.667"/> </StackPanel> </Border> |
XAML |
Copy Code
|
---|---|
<Border... > <StackPanel... > <TextBlock Foreground="White" FontSize="26.667"/> <TextBlock Foreground="White" FontSize="18.667"/> </StackPanel> </Border> |
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 HotelCollection to represent an observable collection of HotelItemViewModel class.
C# |
Copy Code
|
---|---|
public class HotelItemViewModel : ViewModelBase { } |
C# |
Copy Code
|
---|---|
private Hotel _hotel; private string _id; public HotelItemViewModel(Hotel hotel){ this._hotel = hotel;} public string Id { get { return this._id; } set { if (this._id != value) { this._id = value; OnPropertyChanged("Id"); } } } public Hotel Hotel { get { return this._hotel; } set { if (this._hotel != null) { this._hotel = value; OnPropertyChanged("Hotel"); } } } |
C# |
Copy Code
|
---|---|
public class HotelPageViewModel : ViewModelBase { } |
C# |
Copy Code
|
---|---|
private ObservableCollection<HotelItemViewModel> _hotelCollection; private HotelItemViewModel _selectedItem; public ObservableCollection<HotelItemViewModel> HotelCollection { get { return this._hotelCollection; } set { if (this._hotelCollection != value) { this._hotelCollection = value; OnPropertyChanged("HotelCollection"); } } } public HotelItemViewModel SelectedItem { get { return this._selectedItem; } set { if (this._selectedItem != value) { this._selectedItem = value; OnPropertyChanged("SelectedItem"); } } } |
C# |
Copy Code
|
---|---|
public void LoadHotel() { StreamResourceInfo stream = System.Windows.Application.GetResourceStream(new Uri("/DisItemDtailUsingRichUICtrlWithMVVMPat;component/SampleData/HotelDataSource.xml", UriKind.Relative)); XDocument doc = XDocument.Load(stream.Stream); var hotels = doc.Descendants("Hotel").Select(a => new Hotel(a)); _hotelCollection = new ObservableCollection<HotelItemViewModel>(); int i = 0; foreach (var dt in hotels) { dt.Image = "/DisItemDtailUsingRichUICtrlWithMVVMPat;component/Images/Hotels/" + dt.Image; HotelItemViewModel newData = new HotelItemViewModel(dt); newData.Id = i.ToString(); HotelCollection.Add(newData); i++; } stream.Stream.Close(); } |
C# |
Copy Code
|
---|---|
public HotelPageViewModel() { this.LoadHotel(); } |
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 data context and selection.
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage... xmlns:ViewModels="clr-namespace:DisItemDtailUsingRichUICtrlWithMVVMPat.ViewModels"> </Intersoft:UXPage> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage.Resources> <ViewModels:HotelPageViewModel x:Key="HotelPageViewModel" /> ... </Intersoft:UXPage.Resources> <Grid x:Name="LayoutRoot" ... DataContext="{StaticResource HotelPageViewModel}"> </Grid> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage.Resources> ... <DataTemplate x:Key="HotelListTemplate"> <Grid> <Intersoft:ImageLoader ImageSource="{Binding Hotel.Image}" Width="55" ToolTipService.ToolTip="{Binding Hotel.Name}" ToolTipService.Placement="Right" /> </Grid> </DataTemplate> </Intersoft:UXPage.Resources> <Intersoft:UXListBox ItemTemplate="{StaticResource HotelListTemplate}" ... /> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXListBox Name="HotelList" Background="Black" ItemTemplate="{StaticResource HotelListTemplate}" ItemsSource="{Binding HotelCollection}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" SelectionChanged="UXListBox_SelectionChanged" /> |
XAML |
Copy Code
|
---|---|
<Intersoft:CallOut... DataContext="{Binding SelectedItem}" > <Intersoft:CallOut.Background> <ImageBrush... ImageSource="{Binding Hotel.Image}" /> </Intersoft:CallOut.Background> <Border VerticalAlignment="Bottom"> <StackPanel VerticalAlignment="Center" Margin="40,0,0,0"> <TextBlock... Text="{Binding Hotel.Name}" /> <TextBlock... Text="{Binding Hotel.Location}" /> </StackPanel> </Border> </Intersoft:CallOut> |
C# |
Copy Code
|
---|---|
<Intersoft:CallOut TargetElement="{Binding SelectedElement, ElementName=HotelList}" > ...</Intersoft:CallOut> |
After the application is running in the browser, you can try to click on the UXListBox item to change the data context of CallOut, such as shown in the following figure.
In this walkthrough, you have learned how to create ClientUI MVVM project using project template, and create the classes and page based on the Model, View and ViewModel pattern. You also learned how to bind UXListBox to a collection of data, and then bind the CallOut data context to a SelectedItem in the ViewModel which performs data source changes that automatically reflect the data presented in CallOut.
This section lists the complete code used in this walkthrough.
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 DisItemDtailUsingRichUICtrlWithMVVMPat.ViewModels; using System.Xml.Linq; namespace DisItemDtailUsingRichUICtrlWithMVVMPat.Models { public class Hotel : ModelBase { private string _name; private string _location; private string _rating; private string _rate; private string _image; public string Name { get { return this._name; } set { if (this._name != value) { this._name = value; OnPropertyChanged("Name"); } } } public string Location { get { return this._location; } set { if (this._location != value) { this._location = value; OnPropertyChanged("Location"); } } } public string Rating { get { return this._rating; } set { if (this._rating != value) { this._rating = value; OnPropertyChanged("Rating"); } } } public string Rate { get { return this._rate; } set { if (this._rate != value) { this._rate = value; OnPropertyChanged("Rate"); } } } public string Image { get { return this._image; } set { if (this._image != value) { this._image = value; OnPropertyChanged("Image"); } } } public Hotel(XElement x) { this._name = x.Element("Name").Value.Trim(); this._location = x.Element("Location").Value.Trim(); this._rating = x.Element("Rating").Value.Trim(); this._rate = x.Element("Rate").Value.Trim(); this._image = x.Element("Image").Value.Trim(); } } } |
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 DisItemDtailUsingRichUICtrlWithMVVMPat.Models; namespace DisItemDtailUsingRichUICtrlWithMVVMPat.ViewModels { public class HotelItemViewModel : ViewModelBase { private Hotel _hotel; private string _id; public HotelItemViewModel(Hotel hotel) { this._hotel = hotel; } public string Id { get { return this._id; } set { if (this._id != value) { this._id = value; OnPropertyChanged("Id"); } } } public Hotel Hotel { get { return this._hotel; } set { if (this._hotel != null) { this._hotel = value; OnPropertyChanged("Hotel"); } } } } } |
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.Windows.Resources; using System.Xml.Linq; using DisItemDtailUsingRichUICtrlWithMVVMPat.Models; using System.Linq; namespace DisItemDtailUsingRichUICtrlWithMVVMPat.ViewModels { public class HotelPageViewModel : ViewModelBase { private ObservableCollection<HotelItemViewModel> _hotelCollection; private HotelItemViewModel _selectedItem; public HotelPageViewModel() { this.LoadHotel(); } public ObservableCollection<HotelItemViewModel> HotelCollection { get { return this._hotelCollection; } set { if (this._hotelCollection != value) { this._hotelCollection = value; OnPropertyChanged("HotelCollection"); } } } public HotelItemViewModel SelectedItem { get { return this._selectedItem; } set { if (this._selectedItem != value) { this._selectedItem = value; OnPropertyChanged("SelectedItem"); } } } public void LoadHotel() { StreamResourceInfo stream = System.Windows.Application.GetResourceStream(new Uri("/DisItemDtailUsingRichUICtrlWithMVVMPat;component/SampleData/HotelDataSource.xml", UriKind.Relative)); XDocument doc = XDocument.Load(stream.Stream); var hotels = doc.Descendants("Hotel").Select(a => new Hotel(a)); _hotelCollection = new ObservableCollection<HotelItemViewModel>(); int i = 0; foreach (var dt in hotels) { dt.Image = "/DisItemDtailUsingRichUICtrlWithMVVMPat;component/Images/Hotels/" + dt.Image; HotelItemViewModel newData = new HotelItemViewModel(dt); newData.Id = i.ToString(); HotelCollection.Add(newData); i++; } stream.Stream.Close(); } } } |
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:DisItemDtailUsingRichUICtrlWithMVVMPat.ViewModels" mc:Ignorable="d" x:Class="DisItemDtailUsingRichUICtrlWithMVVMPat.Views.HotelPage" Title="UXPage1 Page" d:DesignWidth="640" d:DesignHeight="480"> <Intersoft:UXPage.Resources> <ViewModels:HotelPageViewModel x:Key="HotelPageViewModel" /> <DataTemplate x:Key="HotelListTemplate"> <Grid> <Intersoft:ImageLoader ImageSource="{Binding Hotel.Image}" Width="55" ToolTipService.ToolTip="{Binding Hotel.Name}" ToolTipService.Placement="Right" /> </Grid> </DataTemplate> </Intersoft:UXPage.Resources> <Grid x:Name="LayoutRoot" Background="{x:Null}" Width="640" Height="480" DataContext="{StaticResource vwHotel}"> <Border CornerRadius="20"> <Border.Background> <LinearGradientBrush> <GradientStop Color="Gray" Offset="0.5" /> <GradientStop Color="LightGray" Offset="1" /> </LinearGradientBrush> </Border.Background> <Border.Effect> <DropShadowEffect Color="Gray" /> </Border.Effect> <Intersoft:DockPanel FillChildMode="Custom"> <Intersoft:GlassLabel Content="Hotel" Intersoft:DockPanel.Dock="Top" SpreadBackground="Gray" /> <Intersoft:UXScroller Intersoft:DockPanel.Dock="Left" Margin="10 10 0 10"> <Intersoft:UXListBox Name="HotelList" Background="Black" ItemTemplate="{StaticResource HotelListTemplate}" ItemsSource="{Binding HotelCollection}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" /> </Intersoft:UXScroller> <Intersoft:CallOut Name="HotelCallOut" Visibility="Visible" Intersoft:DockPanel.IsFillElement="True" DataContext="{Binding SelectedItem}" StrokeThickness="0" CornerRadius="10" Grid.Column="1" PointerPosition="Left" PointerPoint1="12, 0" PointerPoint2="0,20" PointerPoint3="-12, 0" Margin="0 20 20 20" TargetElement="{Binding SelectedElement, ElementName=HotelList}"> <Intersoft:CallOut.Background> <ImageBrush Stretch="UniformToFill" ImageSource="{Binding Hotel.Image}" /> </Intersoft:CallOut.Background> <Border VerticalAlignment="Bottom"> <StackPanel VerticalAlignment="Center" Margin="40,0,0,0"> <TextBlock Text="{Binding Hotel.Name}" Foreground="White" FontSize="26.667"/> <TextBlock Text="{Binding Hotel.Location}" Foreground="White" FontSize="18.667"/> </StackPanel> </Border> </Intersoft:CallOut> </Intersoft:DockPanel> </Border> </Grid> </Intersoft:UXPage> |