MOBILE

Windows Phone 7 Advanced Programming Model : Advanced Data Binding (part 1)

9/20/2011 3:40:02 PM
In this article, I cover how to access Syndicated Services like RSS feeds from Windows Phone 7, as well as advanced Model-View-ViewModel (MVVM) techniques to incorporate page navigation, showing progress, and lazy loading images. The last subsection covers the IValueConverter interface, which allows you to data bind any data type to just about any other data.

A sample project based on the MVVM Light project template named AdvancedDataBinding is added to solution. MVVM is leveraged for this example to demonstrate how to handle slightly additional complexity of separating concerns between the View and the ViewModel when dealing with more complex scenarios.

By default, the MainPage.xaml binds to the MainViewModel in the ViewModel folder. MainPage.xaml presents a menu of four items that navigate to individual pages corresponding to the sections that follow:

  • Syndicated Services (/View/SyndicatedServices.xaml)

  • Showing Progress (/View/ShowingProgress.xaml)

  • Lazy Load Images (/View/LazyLoadImages.xaml)

  • Data Bind to Anything (/View/DatabindToAnything.xaml)

MainPage.xaml consists of a ListBoxdatabound to a collection of items that represent the above pages. Here is the XAML:

<ListBox x:Name="listBox1" Margin="24,0,0,0"
ItemsSource="{Binding Pages}"
ItemTemplate="{StaticResource PageItemTemplate}" />

In MainViewModel.cs, the ApplicationTitle and PageName properties are updated for the current project. A Pages property is added to MainViewModel class that is of type List<PageItemViewModel>:

public const string PagesPropertyName = "Pages";
private List<PageItemViewModel> _pages = null;
public List<PageItemViewModel> Pages
{
get
{
return _pages;
}

protected set
{
if (_pages == value)
{
return;
}

var oldValue = _pages;
_pages = value;

// Update bindings, no broadcast
RaisePropertyChanged(PagesPropertyName);
}
}

The MainViewModel class has a method named LoadPageInfo(), which instantiates the Pages collection:

private void LoadPagesInfo()
{
Pages = new List<PageItemViewModel>()
{
new PageItemViewModel(){PageTitle="syndicated services",
PageUri=new Uri("/View/SyndicatedServices.xaml",UriKind.Relative)},
new PageItemViewModel(){PageTitle="showing progress",
PageUri=new Uri("/View/ShowingProgress.xaml",UriKind.Relative)},
new PageItemViewModel(){PageTitle="lazy load images",
PageUri=new Uri("/View/LazyLoadImages.xaml",UriKind.Relative)},
new PageItemViewModel(){PageTitle="data binding to anything",
PageUri=new Uri("/View/DatabindToAnything.xaml",UriKind.Relative)}
};
}

Normally, the PageItem class would be a simple Model class; however, I made it a ViewModel class because of necessary support to allow databinding and navigation from a ListBox displaying the Pages data. When an item is selected in the ListBox shown in Figure 6-1, the application should navigate to the associated page. We don't want to write code to do this in the MainPage.xaml.cs code-behind file. Instead we take advantage of messaging and commanding support provided by the MVVM Light toolkit.

Figure 1. AdvancedDataBinding MainPage.xaml UI

The selected item in the ListBox on MainPage.xaml should perform navigation to the associated page pointed to by the selected item. This means that the Commanding support is required at the PageItem / ItemTemplate level, not at the ListBox level. To support this functionality, a ViewModel class named PageItemViewModel is added that supports GalaSoft Light Messaging and Commanding . Listing 1 shows the PageItemViewModel.

Example 1. PageItemViewModel Class File
using System;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight;
namespace AdvancedDataBinding.ViewModel
{
public class PageItemViewModel : ViewModelBase
{
public PageItemViewModel()
{
//Wire up the NavigateToPageCommand RelayCommand to send the message
//for the Uri of the page to navigate to.
NavigateToPageCommand = new RelayCommand<Uri>(

param => SendNavigationRequestMessage(param));
}

#region PageItem properties
public const string PageTitlePropertyName = "PageTitle";
private string _pageTitle = null;
public string PageTitle
{
get
{
return _pageTitle;
}
set
{
if (_pageTitle == value)
{
return;
}

var oldValue = _pageTitle;
_pageTitle = value;
RaisePropertyChanged(PageTitlePropertyName);
}
}


public const string PageUriPropertyName = "PageUri";
private Uri _pageUri = null;
public Uri PageUri
{
get
{
return _pageUri;
}
set
{
if (_pageUri == value)
{
return;
}

var oldValue = _pageUri;
_pageUri = value;

// Update bindings, no broadcast
RaisePropertyChanged(PageUriPropertyName);
}
}
#endregion

#region Commanding and Messaging
public RelayCommand<Uri> NavigateToPageCommand
{
get;


private set;
}

protected void SendNavigationRequestMessage(Uri uri)
{
Messenger.Default.Send<Uri>(uri, "PageNavRequest");
}
#endregion
}
}

The PageItemViewModel class is broken up into two sections, one for the properties and the other for the Commanding and Messaging support. The PageItemViewModel class has two properties, PageTitle and PageUri. The PageUri points to the appropriate XAML file to navigate to for the PageTitle property value.

The Commanding and Messaging support is pretty simple code. The NavigateToPageCommand is what the MainPage.xaml View DataBinds to when the ListBoxItem is clicked via the MVVM Light EventToCommand Behavior. The NavigateToPageCommandRelayCommand<T> is connected to the MVVM Light Messaging infrastructure via this code in the PageItemViewModel constructor:

NavigateToPageCommand = new RelayCommand<Uri>(
param => SendNavigationRequestMessage(param));

The NavigateToPageCommand takes an Uri and passes it to the SendNavigationRequestMessage. This is a bit of indirection, as the Uri property comes from the ListBox's template and then is sent back to the View via the MVVM Light Messaging infrastructure but it does promote decoupling of the UI from the ViewModel.

The MainPage.xaml View receives the message via this line of code added to the PhoneApplicationPage constructor and uses an inline Lambda statement to call the NavigationService:

Messenger.Default.Register<Uri>(
this, "PageNavRequest",
(uri) => NavigationService.Navigate(uri));

I mentioned earlier that the DataTemplate data binds to the NavigateToPageCommand. Here is the ItemTemplate="{StaticResourcePageItemTemplate}" for the MainPage.ListBox control:

<DataTemplate x:Key="PageItemTemplate">
<Grid Margin="0,15">
<TextBlock Margin="0,0,1,0" TextWrapping="Wrap" Text="{Binding PageTitle}"
d:LayoutOverrides="Width, Height" Style="{StaticResource PhoneTextLargeStyle}">
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="MouseLeftButtonDown">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding NavigateToPageCommand, Mode=OneWay}" CommandParameter="{Binding PageUri}"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</TextBlock>
</Grid>
</DataTemplate>


The EventToCommand behavior is dragged from the Assets | Behaviors section and is dropped on the TextBlock. Figure 2 shows the Properties window for the EventToCommand behavior.

Figure 2. EventToCommand properties in Expression Blend

In Figure 6-2, the Command value is databound to the NavigateToPageCommand property on the PageItemViewModel class. The CommandParameter is databound to PageUri property of the selected item from the MainViewModel Pages collection of type PageItemViewModel.

This was a detailed walkthrough of relatively simple functionality, but it demonstrates the powerful capabilities of MVVM Light's Commanding and Messaging infrastructure to support decoupling UI from the ViewModel via Silverlight's data binding framework.

Other  
  •  Beginning Android 3 : The Input Method Framework - Fitting In
  •  Mobile Application Security : Mobile Geolocation - Geolocation Methods & Geolocation Implementation
  •  Mobile Application Security : SMS Security - Application Attacks & Walkthroughs
  •  iPad SDK : Popovers - The Stroke Width Popover
  •  iPad SDK : Popovers - The Font Size Popover
  •  Beginning Android 3 : The Input Method Framework - Tailored to Your Needs
  •  Beginning Android 3 : Working with Containers - Scrollwork
  •  Mobile Application Security : SMS Security - Protocol Attacks (part 2)
  •  Mobile Application Security : SMS Security - Protocol Attacks (part 1)
  •  Mobile Application Security : SMS Security - Overview of Short Message Service
  •  iPad SDK : Popovers - The Font Name Popover (part 2)
  •  iPad SDK : Popovers - The Font Name Popover (part 1)
  •  Beginning Android 3 : Working with Containers - Tabula Rasa
  •  Beginning Android 3 : Working with Containers - LinearLayout Example & The Box Model
  •  iPhone Application Development : Reading and Writing User Defaults (part 2) - Implementing System Settings
  •  iPhone Application Development : Reading and Writing User Defaults (part 1) - Creating Implicit Preferences
  •  - Mobile Application Security : SMS Security - Overview of Short Message Service
  •  - Mobile Application Security : Bluetooth Security - Bluetooth Security Features
  •  Integrating Your Application with Windows Phone 7
  •  Introducing Windows Phone 7 Photo Features (part 2) - Using a Chooser to Open Photos & Saving Photos to the Phone
  •  
    Top 10
    How To Basics Installing Linux
    How To Basics Virtualization
    Nero 12 Platinum Multimedia Software
    Ten Popular Open Source Media Players
    Top Mind Mapping Tools For Android
    Ultra-portable Devices Eat Into The Legacy PC Market (Part 3)
    Ultra-portable Devices Eat Into The Legacy PC Market (Part 2)
    Ultra-portable Devices Eat Into The Legacy PC Market (Part 1)
    JBL Flip Portable Wireless Loudspeaker
    AOC E2460phu LED LCD 24” Monitor
    Most View
    Top 10 Cameras – November 2012
    Windows Server 2008 R2 Active Directory Domain Services Primer : Outlining AD DS’s Components
    Dynamically Downloading Content with Silverlight
    HP Wireless Multi-function Printer
    Collaborating Within an Exchange Server Environment Using Microsoft Office SharePoint Server 2007 : Understanding the History of SharePoint Technologies
    Pocket Intel (Part 1)
    Buying Guide: For the Compact System Builder...(Part 2) - The H77 boards, The H61 boards
    Windows Vista : Scripting and Automation - Object References (part 3) - How to Manage Windows Services, How to Write CGI Scripts for Web Servers
    SQL Server 2005 : Exception Handling
    Fujifilm X-S1(Part 2)
    High Availability in Exchange Server 2010 : Exchange Server database technologies
    Windows Server : Planning Application Virtualization
    Programming .NET Components : Serialization and Persistence - Serialization Formatters
    The State Of Mobile Gaming 2012 (Part 2)
    Active Directory Domain Services 2008 : Remove a User, Group, or Computer from the Password Replication Policy
    Processor Group Test (Part 3) - Intel Core i3-2100
    Akasa Venom Power 750W Modular PSU - Well-Priced And Handsome PSU
    Buying Guide: High-end CPUs (Part 1) : Intel Core i5-2550K, Intel Core i5-3570K
    Windows Server 2003 : Creating and Managing Digital Certificates - Introducing Certificates
    Apple Announces Release Information For OS X Mountain Lion