Intersoft ClientUI 8 > ClientUI Fundamentals > MVVM Pattern Overview > MVVM Pattern Walkthroughs > Walkthrough: Display Data in UXAccordion using MVVM Pattern |
This walkthrough will show you how to display data to UXAccordion using 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 you how to create the Book model class that represent the data entity used in this walkthrough. To create the Book model class, see Walkthrough: Creating Model for Book Data.
This section steps you through the process of creating the user interface that consists of UXAccordion.
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 |
XAML |
Copy Code
|
---|---|
<Grid Height="320" Width="520"> <Intersoft:UXAccordion Name="uXAccordion1" Padding="2,0" Background="#FFDFDFDF"> </Intersoft:UXAccordion> </Grid> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage.Resources> ... <ItemsPanelTemplate x:Key="AccordionItemTemplate"> <Intersoft:UXGridPanel Column="3" ItemHeight="100" ItemWidth="80"></Intersoft:UXGridPanel> </ItemsPanelTemplate> ... </Intersoft:UXPage.Resources> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage.Resources> ... <Style x:Key="UXAccordionOptionStyle1" TargetType="Intersoft:UXAccordionOption"> <Setter Property="ContentType" Value="Image"/> <Setter Property="ImageHeight" Value="NaN"/> <Setter Property="ImageWidth" Value="NaN"/> </Style> <Style x:Key="UXAccordionItemStyle1" TargetType="Intersoft:UXAccordionItem"> <Setter Property="ItemContainerStyle" Value="{StaticResource UXAccordionOptionStyle1}"/> <Setter Property="ItemsPanel" Value="{StaticResource AccordionItemTemplate}" /> </Style> </Intersoft:UXPage.Resources> |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Grid ...> <Intersoft:UXAccordion Name="uXAccordion1" ... ItemContainerStyle="{StaticResource UXAccordionItemStyle1}" ...> </Intersoft:UXAccordion> </Grid> </Grid> |
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.
C# |
Copy Code
|
---|---|
public class BookViewModel : ViewModelBase { // Fields private Book _book; // Constructor public BookViewModel() { } public BookViewModel(Book book) { _book = book; } // Views public Book Book { get { return this._book; } set { if (this._book != value) { this._book = value; OnPropertyChanged("Book"); } } } public string Title { get { return this.Book.Title; } } } |
C# |
Copy Code
|
---|---|
public class BookCategoryViewModel : ViewModelBase { // Fields private ObservableCollection<BookViewModel> _books; private string _name; // Constructor public BookCategoryViewModel() { } public BookCategoryViewModel(string name) { this._name = name; } public ObservableCollection<BookViewModel> Books { get { if (this._books == null) this._books = new ObservableCollection<BookViewModel>(); return this._books; } } public string Name { get { return this._name; } set { if (this._name != value) { this._name = value; this.OnPropertyChanged("Name"); } } } } |
C# |
Copy Code
|
---|---|
public ObservableCollection<BookCategoryViewModel> Categories { get; set; } // Constructors public BooksListViewModel() { this.LoadBooks(); } // Methods private void LoadBooks() { // loads book data from xml file StreamResourceInfo resource = System.Windows.Application.GetResourceStream( new Uri("MVVMWithUXAccordion;component/Data/BookDataSource.xml", UriKind.Relative)); XDocument doc = XDocument.Load(resource.Stream); var books = from x in doc.Descendants("Book") select new Book(x); this.Categories = new ObservableCollection<BookCategoryViewModel>(); Dictionary<string, BookCategoryViewModel> dictionary = new Dictionary<string, BookCategoryViewModel>(); foreach (Book book in books) { BookViewModel vm = new BookViewModel(book); if (dictionary.ContainsKey(book.Category)) { BookCategoryViewModel category = dictionary[book.Category]; category.Books.Add(vm); } else { BookCategoryViewModel category = new BookCategoryViewModel(book.Category); category.Books.Add(vm); dictionary.Add(book.Category, category); this.Categories.Add(category); } } resource.Stream.Close(); } |
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.
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage ... xmlns:ViewModels="clr-namespace:MVVMWithUXAccordion.ViewModels" ...> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage...> <Intersoft:UXPage.Resources> <ViewModels:BooksListViewModel x:Key="BooksData" /> </Intersoft:UXPage.Resources> ... </Intersoft:UXPage> |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Grid Height="320" Width="520" DataContext="{Binding Source={StaticResource BooksData}}"> </Grid> </Grid> |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Grid ...> <Intersoft:UXAccordion Name="uXAccordion1" Padding="2,0" Background="#FFDFDFDF" ItemsSource="{Binding Path=Categories}"> </Intersoft:UXAccordion> </Grid> </Grid> |
DisplayMemberPath | Name |
CollectionMemberPath | Books |
OptionDisplayMemberPath | Title |
OptionImageMemberPath | Book.Image |
SelectedIndex | 2 |
ExpandDirection | Right |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Grid ...> <Intersoft:UXAccordion Name="uXAccordion1" Padding="2,0" Background="#FFDFDFDF" ItemsSource="{Binding Path=Categories}" DisplayMemberPath="Name" CollectionMemberPath="Books" OptionDisplayMemberPath="Title" OptionImageMemberPath="Book.Image" SelectedIndex="2" ExpandDirection="Right"> </Intersoft:UXAccordion> </Grid> </Grid> |
In this walkthrough, you have learned how to create ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template, and create the classes and page based on the Model, View and ViewModel pattern. You also learned how to bind UXAccordion to a collection of books that are grouped by category.
To learn more about UI development using MVVM pattern, see MVVM Pattern Overview.
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 MVVMWithUXAccordion.ViewModels; using System.Xml.Linq; namespace MVVMWithUXAccordion.Models { public class Book:ModelBase { #region Constructors public Book() { } public Book(XElement x) : this() { this._author = x.Element("Author").Value.Trim(); this._title = x.Element("Title").Value.Trim(); this._category = x.Element("Category").Value.Trim(); this._ID = x.Element("ID").Value.Trim(); this._price = double.Parse(x.Element("Price").Value.Trim()); this._image = new Uri("/MVVMWithUXAccordion;component/Images/Books/" + x.Element("Image").Value.Trim(), UriKind.RelativeOrAbsolute); } #endregion #region Fields private Uri _image = null; private string _author; private string _title; private string _category; private string _ID; private double _price; #endregion #region Properties public bool EnableValidation { get; set; } public string Author { get { return _author; } set { if (_author != value) { _author = value; ClearError("Author"); OnPropertyChanged("Author"); } } } public string Title { get { return _title; } set { if (_title != value) { _title = value; ClearError("Title"); if (EnableValidation && string.IsNullOrEmpty(this.Title)) SetError("Title", "Title is required"); OnPropertyChanged("Title"); } } } public string Category { get { return _category; } set { if (_category != value) { _category = value; OnPropertyChanged("Category"); } } } public string ID { get { return _ID; } set { if (_ID != value) { _ID = value; OnPropertyChanged("ID"); } } } public double Price { get { return _price; } set { if (_price != value) { _price = value; ClearError("Price"); if (EnableValidation && (double.IsNaN(this.Price) || this.Price == 0.0)) SetError("Price", "Price is required"); OnPropertyChanged("Price"); } } } public Uri Image { get { return _image; } set { if (_image != value) { _image = value; OnPropertyChanged("Image"); } } } #endregion } } |
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 MVVMWithUXAccordion.Models; namespace MVVMWithUXAccordion.ViewModels { public class BookViewModel : ViewModelBase { // Fields private Book _book; // Constructor public BookViewModel() { } public BookViewModel(Book book) { _book = book; } // Views public Book Book { get { return this._book; } set { if (this._book != value) { this._book = value; OnPropertyChanged("Book"); } } } public string Title { get { return this.Book.Title; } } } } |
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.Collections.ObjectModel; namespace MVVMWithUXAccordion.ViewModels { public class BookCategoryViewModel : ViewModelBase { // Fields private ObservableCollection<BookViewModel> _books; private string _name; // Constructor public BookCategoryViewModel() { } public BookCategoryViewModel(string name) { this._name = name; } public ObservableCollection<BookViewModel> Books { get { if (this._books == null) this._books = new ObservableCollection<BookViewModel>(); return this._books; } } public string Name { get { return this._name; } set { if (this._name != value) { this._name = value; this.OnPropertyChanged("Name"); } } } } } |
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 System.Linq; using MVVMWithUXAccordion.Models; using System.Collections.Generic; namespace MVVMWithUXAccordion.ViewModels { public class BooksListViewModel : ViewModelBase { // Views public ObservableCollection<BookViewModel> Books { get; set; } public ObservableCollection<BookCategoryViewModel> Categories { get; set; } // Constructors public BooksListViewModel() { this.LoadBooks(); } // Methods private void LoadBooks() { // loads book data from xml file StreamResourceInfo resource = System.Windows.Application.GetResourceStream( new Uri("MVVMWithUXAccordion;component/Data/BookDataSource.xml", UriKind.Relative)); XDocument doc = XDocument.Load(resource.Stream); var books = from x in doc.Descendants("Book") select new Book(x); this.Categories = new ObservableCollection<BookCategoryViewModel>(); Dictionary<string, BookCategoryViewModel> dictionary = new Dictionary<string, BookCategoryViewModel>(); if (dictionary.ContainsKey(book.Category)) { BookViewModel vm = new BookViewModel(book); this.Books.Add(vm); { BookCategoryViewModel category = dictionary[book.Category]; category.Books.Add(vm); } else { BookCategoryViewModel category = new BookCategoryViewModel(book.Category); category.Books.Add(vm); dictionary.Add(book.Category, category); this.Categories.Add(category); } } resource.Stream.Close(); } protected virtual void InvalidateCommands() { } } } |
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:MVVMWithUXAccordion.ViewModels" mc:Ignorable="d" x:Class="MVVMWithUXAccordion.Views.BooksList" Title="BooksList Page" d:DesignWidth="640" d:DesignHeight="480"> <Intersoft:UXPage.Resources> <ViewModels:BooksListViewModel x:Key="BooksData" /> <ItemsPanelTemplate x:Key="AccordionItemTemplate"> <Intersoft:UXGridPanel Column="3" ItemHeight="100" ItemWidth="80"></Intersoft:UXGridPanel> </ItemsPanelTemplate> <Style x:Key="UXAccordionOptionStyle1" TargetType="Intersoft:UXAccordionOption"> <Setter Property="ContentType" Value="Image"/> <Setter Property="ImageHeight" Value="NaN"/> <Setter Property="ImageWidth" Value="NaN"/> </Style> <Style x:Key="UXAccordionItemStyle1" TargetType="Intersoft:UXAccordionItem"> <Setter Property="ItemContainerStyle" Value="{StaticResource UXAccordionOptionStyle1}"/> <Setter Property="ItemsPanel" Value="{StaticResource AccordionItemTemplate}" /> </Style> </Intersoft:UXPage.Resources> <Grid x:Name="LayoutRoot"> <Grid Height="320" Width="520" DataContext="{Binding Source={StaticResource BooksData}}"> <Intersoft:UXAccordion Name="uXAccordion1" Padding="2,0" Background="#FFDFDFDF" ItemsSource="{Binding Path=Categories}" ItemContainerStyle="{StaticResource UXAccordionItemStyle1}" DisplayMemberPath="Name" CollectionMemberPath="Books" OptionDisplayMemberPath="Title" OptionImageMemberPath="Book.Image" SelectedIndex="2" ExpandDirection="Right"> </Intersoft:UXAccordion> </Grid> </Grid> </Intersoft:UXPage> |