Intersoft ClientUI 8 > Getting Started > Getting Started Walkthroughs > Walkthrough: Create Your First ClientUI Application using MVVM Pattern |
This walkthrough shows how to create simple contacts list application using ClientUI and MVVM pattern. The following figure shows the result that you will achieve upon completing this walkthrough.
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.
Next, you will create the Contact model class that represent the data entity used in this walkthrough.
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.
This section steps you through the process of creating the user interface for your simple contacts list application using ClientUI controls such as GlassLabel, ContentTransition and UXListBox.
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 x:Name="LayoutRoot"> <Intersoft:DockPanel Width="640"> </Intersoft:DockPanel> </Grid> |
Property | Value |
---|---|
Height | 50 |
FontSize | 21 |
Content | My Contact |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Intersoft:DockPanel Width="640" FillChildMode="Custom"> <Intersoft:GlassLabel Content="My Contact" Height="50" FontSize="21" Intersoft:DockPanel.Dock="Top" /> </Intersoft:DockPanel> </Grid> |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Intersoft:DockPanel Width="640" FillChildMode="Custom"> <Intersoft:GlassLabel Content="My Contact" Height="50" FontSize="21" Intersoft:DockPanel.Dock="Top" /> <Intersoft:ContentTransition Intersoft:DockPanel.IsFillElement="True"> </Intersoft:ContentTransition> </Intersoft:DockPanel> </Grid> |
XAML |
Copy Code
|
---|---|
<Grid x:Name="LayoutRoot"> <Intersoft:DockPanel Width="640" FillChildMode="Custom"> <Intersoft:GlassLabel Content="My Contact" Height="50" FontSize="21" Intersoft:DockPanel.Dock="Top" /> <Intersoft:ContentTransition Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox Name="uXListBox1" HorizontalScrollBarVisibility="Disabled" AllowReorderItem="True"> </Intersoft:UXListBox> </Intersoft:ContentTransition> </Intersoft:DockPanel> </Grid> |
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage.Resources> <DataTemplate x:Key="ContactViewTemplate"> <Grid Height="106"> <Grid.ColumnDefinitions> <ColumnDefinition Width="74"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Intersoft:ContentReflector HorizontalAlignment="Left" VerticalAlignment="Top" ContentHeight="64"> <Image/> </Intersoft:ContentReflector> <StackPanel Grid.Column="1" HorizontalAlignment="Left" Orientation="Vertical" VerticalAlignment="Top" Margin="0,7,0,0"> <TextBlock d:LayoutOverrides="Width" Foreground="#FF838383" Margin="0,3"/> <TextBlock d:LayoutOverrides="Width" Margin="0,3"/> <TextBlock Margin="0,3"/> </StackPanel> <Border Grid.Column="1" HorizontalAlignment="Left" Margin="250,5,10,10" VerticalAlignment="Center" Width="300" Padding="10" CornerRadius="8" Background="#7FEBEBEB"> <StackPanel Orientation="Vertical" Height="86"> <Intersoft:UXHyperlinkButton BorderThickness="0" DisplayMode="ContentAndImage" Icon="/MVVMApplicationWalkthrough;component/Assets/Icons/0161-write_email.png" IsToggleButton="False" ToolTipService.ToolTip="Email this contact." HorizontalAlignment="Left"/> <Intersoft:UXHyperlinkButton BorderThickness="0" DisplayMode="ContentAndImage" Icon="/MVVMApplicationWalkthrough;component/Assets/Icons/twitter.png" IsToggleButton="False" ToolTipService.ToolTip="See latest Twitter updates." HorizontalAlignment="Left" TargetName="_blank" ShowUnderlineOnHover="False"/> <Intersoft:UXHyperlinkButton BorderThickness="0" DisplayMode="ContentAndImage" Icon="/MVVMApplicationWalkthrough;component/Assets/Icons/5000-web.png" IsToggleButton="False" ToolTipService.ToolTip="Visit the website." HorizontalAlignment="Left" TargetName="_blank" ShowUnderlineOnHover="False"/> </StackPanel> </Border> <Intersoft:UXSeparator VerticalAlignment="Bottom" Grid.ColumnSpan="2" Background="#FFD8D8D8"/> </Grid> </DataTemplate> </Intersoft:UXPage.Resources> |
XAML |
Copy Code
|
---|---|
... <Intersoft:ContentTransition Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox Name="uXListBox1" HorizontalScrollBarVisibility="Disabled" AllowReorderItem="True" ItemTemplate="{StaticResource ContactViewTemplate}"> </Intersoft:UXListBox> </Intersoft:ContentTransition> ... |
XAML |
Copy Code
|
---|---|
... <Intersoft:DockPanel Width="640" FillChildMode="Custom"> <Intersoft:GlassLabel Content="My Contact" Height="50" FontSize="21" Intersoft:DockPanel.Dock="Top" /> <Intersoft:ContentTransition Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox Name="uXListBox1" HorizontalScrollBarVisibility="Disabled" AllowReorderItem="True" ItemTemplate="{StaticResource ContactViewTemplate}"> </Intersoft:UXListBox> </Intersoft:ContentTransition> <Border BorderBrush="Silver" Height="30" Name="border1" Intersoft:DockPanel.Dock="Bottom" Background="#FF2A2A2A"> </Border> </Intersoft:DockPanel> ... |
XAML |
Copy Code
|
---|---|
... <Border BorderBrush="Silver" Height="30" Name="border1" Intersoft:DockPanel.Dock="Bottom" Background="#FF2A2A2A"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> </StackPanel> </Border> ... |
XAML |
Copy Code
|
---|---|
... <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <TextBlock Foreground="White" VerticalAlignment="Center"/> </StackPanel> ... |
Property | Value |
---|---|
Orientation | Vertical |
Height | 16 |
Width | 1 |
Margin | 10,0 |
XAML |
Copy Code
|
---|---|
... <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <TextBlock Foreground="White" VerticalAlignment="Center"/> <Intersoft:UXSeparator Orientation="Vertical" Height="16" Width="1" Margin="10,0"/> </StackPanel> ... |
XAML |
Copy Code
|
---|---|
... <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <TextBlock Foreground="White" VerticalAlignment="Center"/> <Intersoft:UXSeparator Orientation="Vertical" Height="16" Width="1" Margin="10,0"/> <TextBlock Foreground="White" VerticalAlignment="Center" /> </StackPanel> ... |
Next, you will create the ViewModel that describe the View you just created.
In the ContactsList.xaml page you just created, there are several UXHyperLinkButton instances defined in the ItemTemplate used to navigate to an external URI provided by Twitter, Blog and Email properties in the Contact model.
In order for the UXHyperLinkButton to work properly, the format for email uri should be in the form of "mail-to: [email address]". Since Contact model only provide the email address, you need to extend the Contact model to ContactView model that has extended property such as EmailUri along with the original Contact reference.
C# |
Copy Code
|
---|---|
public class ContactViewModel : ViewModelBase { } |
C# |
Copy Code
|
---|---|
public class ContactViewModel : ViewModelBase { // Fields private Contact _contact; // Constructor public ContactViewModel(Contact contact) { _contact = contact; } // Views public Contact Contact { get { return this._contact; } } public string EmailUri { get { return "mailto:" + _contact.Email; } } } |
Next, you will create the ContactsListViewModel that describes the ContactsList.xaml page.
You will create four properties in ContactsListViewModel to be used in the ContactList.xaml page, which are listed in the following:
C# |
Copy Code
|
---|---|
public class ContactsListViewModel : ViewModelBase { } |
C# |
Copy Code
|
---|---|
public class ContactsListViewModel : ViewModelBase { #region Constructor public ContactsListViewModel() { this.LoadContacts(); this.Contacts.CollectionChanged += new NotifyCollectionChangedEventHandler(Contacts_CollectionChanged); } #endregion #region Fields private ContactViewModel _selectedItem = null; #endregion #region Properties public ObservableCollection<ContactViewModel> 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 SelectedItem { get { return _selectedItem; } set { if (_selectedItem != value) { if (_selectedItem != null) _selectedItem.Contact.PropertyChanged -= new PropertyChangedEventHandler(Contact_PropertyChanged); if (value != null) value.Contact.PropertyChanged += new PropertyChangedEventHandler(Contact_PropertyChanged); _selectedItem = value; OnPropertyChanged("SelectedItem"); OnPropertyChanged("SelectionStatus"); } } } public string SelectionStatus { get { if (this.SelectedItem == null) return "No contact selected"; else return "Selected contact: " + this.SelectedItem.Contact.Name; } } #endregion #region Methods private void LoadContacts() { // loads contact data from xml file StreamResourceInfo resource = System.Windows.Application.GetResourceStream( new Uri("MVVMApplicationWalkthrough;component/App_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<ContactViewModel>(); foreach (Contact contact in contacts) { contact.SetPhoto(this.Contacts.Count.ToString()); this.Contacts.Add(new ContactViewModel(contact)); } resource.Stream.Close(); } private void Contact_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Name") OnPropertyChanged("SelectionStatus"); } private void Contacts_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { OnPropertyChanged("ContactsCount"); } #endregion } |
Next, you will bind the ContactsListViewModel to your ContactsList.xaml.
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 sections shows how to instantiate the ContactsListViewModel in the ContactsList.xaml page and bind the UI elements to the properties in the ContactsListViewModel such as Contacts and SelectedItem.
XAML |
Copy Code
|
---|---|
<Intersoft:UXPage.DataContext> <ViewModels:ContactsListViewModel /> </Intersoft:UXPage.DataContext> |
XAML |
Copy Code
|
---|---|
... <Intersoft:ContentTransition Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox ItemsSource="{Binding Contacts}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" Name="uXListBox1" HorizontalScrollBarVisibility="Disabled" AllowReorderItem="True" ItemTemplate="{StaticResource ContactViewTemplate}"> </Intersoft:UXListBox> </Intersoft:ContentTransition> ... |
XAML |
Copy Code
|
---|---|
... <DataTemplate x:Key="ContactViewTemplate"> <Grid Height="106"> <Grid.ColumnDefinitions> <ColumnDefinition Width="74"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Intersoft:ContentReflector HorizontalAlignment="Left" VerticalAlignment="Top" ContentHeight="64"> <Image Source="{Binding Contact.Photo}"/> </Intersoft:ContentReflector> <StackPanel Grid.Column="1" HorizontalAlignment="Left" Orientation="Vertical" VerticalAlignment="Top" Margin="0,7,0,0"> <TextBlock d:LayoutOverrides="Width" Foreground="#FF838383" Margin="0,3" Text="{Binding Contact.Id}"/> <TextBlock d:LayoutOverrides="Width" Margin="0,3" Text="{Binding Contact.Name}"/> <TextBlock Margin="0,3" Text="{Binding Contact.Phone}"/> </StackPanel> <Border Grid.Column="1" HorizontalAlignment="Left" Margin="250,5,10,10" VerticalAlignment="Center" Width="300" Padding="10" CornerRadius="8" Background="#7FEBEBEB"> <StackPanel Orientation="Vertical" Height="86"> <Intersoft:UXHyperlinkButton Content="{Binding Contact.Email}" BorderThickness="0" DisplayMode="ContentAndImage" Icon="/MVVMApplicationWalkthrough;component/Assets/Icons/0161-write_email.png" NavigateUri="{Binding Contact.Email}" IsToggleButton="False" ToolTipService.ToolTip="Email this contact." HorizontalAlignment="Left"/> <Intersoft:UXHyperlinkButton Content="{Binding Contact.Twitter}" BorderThickness="0" DisplayMode="ContentAndImage" Icon="/MVVMApplicationWalkthrough;component/Assets/Icons/twitter.png" NavigateUri="{Binding Contact.Twitter}" IsToggleButton="False" ToolTipService.ToolTip="See latest Twitter updates." HorizontalAlignment="Left" TargetName="_blank" ShowUnderlineOnHover="False"/> <Intersoft:UXHyperlinkButton Content="{Binding Contact.Website}" BorderThickness="0" DisplayMode="ContentAndImage" Icon="/MVVMApplicationWalkthrough;component/Assets/Icons/5000-web.png" NavigateUri="{Binding Contact.Website}" IsToggleButton="False" ToolTipService.ToolTip="Visit the website." HorizontalAlignment="Left" TargetName="_blank" ShowUnderlineOnHover="False"/> </StackPanel> </Border> <Intersoft:UXSeparator VerticalAlignment="Bottom" Grid.ColumnSpan="2" Background="#FFD8D8D8"/> </Grid> </DataTemplate> ... |
XAML |
Copy Code
|
---|---|
... <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <TextBlock Foreground="White" VerticalAlignment="Center" Text="{Binding ContactsCount}"/> <Intersoft:UXSeparator Orientation="Vertical" Height="16" Width="1" Margin="10,0"/> <TextBlock Foreground="White" VerticalAlignment="Center" Text="{Binding SelectionStatus}" /> </StackPanel> ... |
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 UXListBox to a collection of data and how to use ItemTemplate to display the contact detail.
For more information about application 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 MVVMApplicationWalkthrough.ViewModels; using System.ComponentModel; using System.Xml.Linq; namespace MVVMApplicationWalkthrough.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 } } |
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:MVVMApplicationWalkthrough.ViewModels" mc:Ignorable="d" x:Class="MVVMApplicationWalkthrough.Views.ContactsList" Title="ContactsList Page" d:DesignWidth="640" d:DesignHeight="480" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> <Intersoft:UXPage.DataContext> <ViewModels:ContactsListViewModel /> </Intersoft:UXPage.DataContext> <Intersoft:UXPage.Resources> <DataTemplate x:Key="ContactViewTemplate"> <Grid Height="106"> <Grid.ColumnDefinitions> <ColumnDefinition Width="74"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Intersoft:ContentReflector HorizontalAlignment="Left" VerticalAlignment="Top" ContentHeight="64"> <Image Source="{Binding Contact.Photo}"/> </Intersoft:ContentReflector> <StackPanel Grid.Column="1" HorizontalAlignment="Left" Orientation="Vertical" VerticalAlignment="Top" Margin="0,7,0,0"> <TextBlock d:LayoutOverrides="Width" Foreground="#FF838383" Margin="0,3" Text="{Binding Contact.Id}"/> <TextBlock d:LayoutOverrides="Width" Margin="0,3" Text="{Binding Contact.Name}"/> <TextBlock Margin="0,3" Text="{Binding Contact.Phone}"/> </StackPanel> <Border Grid.Column="1" HorizontalAlignment="Left" Margin="250,5,10,10" VerticalAlignment="Center" Width="300" Padding="10" CornerRadius="8" Background="#7FEBEBEB"> <StackPanel Orientation="Vertical" Height="86"> <Intersoft:UXHyperlinkButton Content="{Binding Contact.Email}" BorderThickness="0" DisplayMode="ContentAndImage" Icon="/MVVMApplicationWalkthrough;component/Assets/Icons/0161-write_email.png" NavigateUri="{Binding Email}" IsToggleButton="False" ToolTipService.ToolTip="Email this contact." HorizontalAlignment="Left"/> <Intersoft:UXHyperlinkButton Content="{Binding Contact.Twitter}" BorderThickness="0" DisplayMode="ContentAndImage" Icon="/MVVMApplicationWalkthrough;component/Assets/Icons/twitter.png" NavigateUri="{Binding Twitter}" IsToggleButton="False" ToolTipService.ToolTip="See latest Twitter updates." HorizontalAlignment="Left" TargetName="_blank" ShowUnderlineOnHover="False"/> <Intersoft:UXHyperlinkButton Content="{Binding Contact.Website}" BorderThickness="0" DisplayMode="ContentAndImage" Icon="/MVVMApplicationWalkthrough;component/Assets/Icons/5000-web.png" NavigateUri="{Binding Website}" IsToggleButton="False" ToolTipService.ToolTip="Visit the website." HorizontalAlignment="Left" TargetName="_blank" ShowUnderlineOnHover="False"/> </StackPanel> </Border> <Intersoft:UXSeparator VerticalAlignment="Bottom" Grid.ColumnSpan="2" Background="#FFD8D8D8"/> </Grid> </DataTemplate> </Intersoft:UXPage.Resources> <Grid x:Name="LayoutRoot"> <Intersoft:DockPanel Width="640" FillChildMode="Custom"> <Intersoft:GlassLabel Content="My Contact" Height="50" FontSize="21" Intersoft:DockPanel.Dock="Top" /> <Intersoft:ContentTransition Intersoft:DockPanel.IsFillElement="True"> <Intersoft:UXListBox ItemsSource="{Binding Contacts}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" Name="uXListBox1" HorizontalScrollBarVisibility="Disabled" AllowReorderItem="True" ItemTemplate="{StaticResource ContactViewTemplate}"> </Intersoft:UXListBox> </Intersoft:ContentTransition> <Border BorderBrush="Silver" Height="30" Name="border1" Intersoft:DockPanel.Dock="Bottom" Background="#FF2A2A2A"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <TextBlock Foreground="White" VerticalAlignment="Center" Text="{Binding ContactsCount}"/> <Intersoft:UXSeparator Orientation="Vertical" Height="16" Width="1" Margin="10,0"/> <TextBlock Foreground="White" VerticalAlignment="Center" Text="{Binding SelectionStatus}" /> </StackPanel> </Border> </Intersoft:DockPanel> </Grid> </Intersoft:UXPage> |
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 MVVMApplicationWalkthrough.Models; namespace MVVMApplicationWalkthrough.ViewModels { public class ContactViewModel : ViewModelBase { // Fields private Contact _contact; // Constructor public ContactViewModel(Contact contact) { _contact = contact; } // Views public Contact Contact { get { return this._contact; } } public string EmailUri { get { return "mailto:" + _contact.Email; } } } } |
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.ComponentModel; using System.Collections.Specialized; using System.Windows.Resources; using System.Xml.Linq; using System.Linq; using MVVMApplicationWalkthrough.Models; namespace MVVMApplicationWalkthrough.ViewModels { public class ContactsListViewModel : ViewModelBase { #region Constructor public ContactsListViewModel() { this.LoadContacts(); this.Contacts.CollectionChanged += new NotifyCollectionChangedEventHandler(Contacts_CollectionChanged); } #endregion #region Fields private ContactViewModel _selectedItem = null; #endregion #region Properties public ObservableCollection<ContactViewModel> 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 SelectedItem { get { return _selectedItem; } set { if (_selectedItem != value) { if (_selectedItem != null) _selectedItem.Contact.PropertyChanged -= new PropertyChangedEventHandler(Contact_PropertyChanged); if (value != null) value.Contact.PropertyChanged += new PropertyChangedEventHandler(Contact_PropertyChanged); _selectedItem = value; OnPropertyChanged("SelectedItem"); OnPropertyChanged("SelectionStatus"); } } } public string SelectionStatus { get { if (this.SelectedItem == null) return "No contact selected"; else return "Selected contact: " + this.SelectedItem.Contact.Name; } } #endregion #region Methods private void LoadContacts() { // loads contact data from xml file StreamResourceInfo resource = System.Windows.Application.GetResourceStream( new Uri("MVVMApplicationWalkthrough;component/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<ContactViewModel>(); foreach (Contact contact in contacts) { contact.SetPhoto(this.Contacts.Count.ToString()); this.Contacts.Add(new ContactViewModel(contact)); } resource.Stream.Close(); } private void Contact_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Name") OnPropertyChanged("SelectionStatus"); } private void Contacts_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { OnPropertyChanged("ContactsCount"); } #endregion } } |