MVVM – Windows Phone 8 App using XAML/C#.NET Primer
Purpose: The purpose of this document is to illustrate how to how to apply MVVM (Model-View-ViewModel) architectural pattern when developing Windows Phone 8 Product catalog App using XAML/C#.NET
Challenge: You may need to develop a modern application integrated with Microsoft Dynamics AX 2012 for the purposes of demonstration, POC or to be deployed in production environment. The question is what technology and architectural   pattern to use in order to facilitate application development and maintenance efforts         
Solution: In this scenario we'll leverage Windows Phone 8 SDK for developing Windows Phone 8 App using XAML/C#.NET
Walkthrough
First off let's create a new project using Visual C# > Windows Phone > Windows Phone App template
New Project
Target Windows Phone OS Version 
Then we'll apply MVVM (Model-View-ViewModel) architectural pattern for development of Product catalog app
Solution Explorer
For the sake of clarity I created 3 folders for Model, View and ViewModel
The model encapsulates business logic and data. Please see below how I define Product class which has 2 attributes: ID and Name as a part of the model
Model
| 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
namespace PhoneApp1.Model 
{ 
     public  class  Product 
    { 
         public  string ID {  get;  set; } 
         public  string Name {  get;  set; } 
    } 
} | 
The view model encapsulates presentation logic and state. Please see below how I define ObservableCollection of products with respective method(s) (GetProducts) as a part of the view model
ViewModel
| 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.ComponentModel; 
using System.Collections.ObjectModel; 
using PhoneApp1.Model; 
namespace PhoneApp1.ViewModel 
{ 
     public  class  ProductViewModel 
    { 
         private  ObservableCollection<Product>   _Products = new  ObservableCollection<Product>(); 
         public  ObservableCollection<Product>   Products 
        { 
             get 
            { 
                 return _Products; 
            } 
             set 
            { 
                _Products =  value; 
            } 
        } 
         public  void GetProducts() 
        { 
             Product product; 
            product =  new  Product(); 
            product.ID =  "X"; 
            product.Name =  "AlexProductX"; 
            Products.Add(product); 
        } 
    } 
} | 
The view encapsulates the UI and any UI logic. Please see below how I instantiate an object of view model class to retrieve a list of products
View (ProductsPage.xaml.cs)
| 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Navigation; 
using Microsoft.Phone.Controls; 
using Microsoft.Phone.Shell; 
using PhoneApp1.Model; 
using PhoneApp1.ViewModel; 
namespace PhoneApp1.View 
{ 
     public  partial  class  ProductsPage :  PhoneApplicationPage 
    { 
         public ProductsPage() 
        { 
            InitializeComponent(); 
             ProductViewModel productViewModel =  new  ProductViewModel(); 
            productViewModel.GetProducts(); 
             this.DataContext = productViewModel; 
        }                  
    } 
} | 
And then I use bindings to link product metadata to respective UI elements for display
XAML (ProductPage.xaml)
| 
<phone:PhoneApplicationPage 
     x:Class="PhoneApp1.View.ProductsPage" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
     xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     FontFamily="{StaticResource   PhoneFontFamilyNormal}" 
     FontSize="{StaticResource   PhoneFontSizeNormal}" 
     Foreground="{StaticResource   PhoneForegroundBrush}" 
     SupportedOrientations="Portrait"   Orientation="Portrait" 
     mc:Ignorable="d" 
     shell:SystemTray.IsVisible="True"> 
     <phone:PhoneApplicationPage.Resources> 
         <DataTemplate   x:Key="ProductDataTemplate"> 
             <Grid   Width="400" Height="100"   Background="White"> 
                 <Grid.ColumnDefinitions> 
                    <ColumnDefinition   Width="100"/> 
                     <ColumnDefinition/> 
                 </Grid.ColumnDefinitions> 
                 <Grid.RowDefinitions> 
                     <RowDefinition   Height="Auto"/> 
                 </Grid.RowDefinitions> 
                 <Border   BorderThickness="2" BorderBrush="White"   Height="100" VerticalAlignment="Top"   Background="Black"> 
                     <TextBlock   TextWrapping="Wrap" Text="{Binding   ID}" Style="{StaticResource   PhoneTextNormalStyle}" VerticalAlignment="Center"   HorizontalAlignment="Center"/> 
                 </Border> 
                 <TextBlock   HorizontalAlignment="Left" TextWrapping="Wrap"   Text="{Binding   Name}" VerticalAlignment="Top"   Style="{StaticResource   PhoneTextSubtleStyle}" Margin="10,5,10,0"   Grid.Column="1" Foreground="Black"/> 
             </Grid> 
         </DataTemplate> 
     </phone:PhoneApplicationPage.Resources> 
     <!--LayoutRoot is the root grid where all page content is placed--> 
     <Grid   x:Name="LayoutRoot"   Background="Transparent"> 
        <Grid.RowDefinitions> 
             <RowDefinition   Height="Auto"/> 
             <RowDefinition   Height="*"/> 
         </Grid.RowDefinitions> 
         <!--TitlePanel contains the name of the application and page title--> 
         <StackPanel   Grid.Row="0" Margin="12,17,0,28"> 
             <TextBlock   Text="Product Catalog" Style="{StaticResource   PhoneTextNormalStyle}" Margin="12,0"/> 
             <TextBlock   Text="Product Catalog" Margin="9,-7,0,0"   Style="{StaticResource   PhoneTextTitle1Style}"/> 
         </StackPanel> 
         <!--ContentPanel - place additional content here--> 
         <Grid   x:Name="ContentPanel"   Grid.Row="1" Margin="12,0,12,0"> 
             <phone:LongListSelector   x:Name="ProductLongListSelector"   ItemsSource="{Binding   Products}" ItemTemplate="{StaticResource   ProductDataTemplate}"/> 
         </Grid> 
     </Grid> 
</phone:PhoneApplicationPage> | 
Please note that LongListSelector control was specifically designed for phone scenarios and it is encouraged to use the LongListSelector instead of ListBox for phone apps
Please note that I used ItemTemplate to define a style. You can easily generate ItemTemplate as shown below   
Document Outline
And then define a style for any UI element as you wish
ProductsPage.xaml (ProductDataTemplate)
| 
<phone:PhoneApplicationPage 
     x:Class="PhoneApp1.View.ProductsPage" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
     xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     FontFamily="{StaticResource   PhoneFontFamilyNormal}" 
     FontSize="{StaticResource   PhoneFontSizeNormal}" 
     Foreground="{StaticResource   PhoneForegroundBrush}" 
     SupportedOrientations="Portrait"   Orientation="Portrait" 
     mc:Ignorable="d" 
     shell:SystemTray.IsVisible="True"> 
     <phone:PhoneApplicationPage.Resources> 
         <DataTemplate   x:Key="ProductDataTemplate"> 
             <Grid   Width="400" Height="100"   Background="White"> 
                <Grid.ColumnDefinitions> 
                     <ColumnDefinition   Width="100"/> 
                     <ColumnDefinition/> 
                 </Grid.ColumnDefinitions> 
                 <Grid.RowDefinitions> 
                     <RowDefinition   Height="Auto"/> 
                </Grid.RowDefinitions> 
                 <Border   BorderThickness="2" BorderBrush="White"   Height="100" VerticalAlignment="Top"   Background="Black"> 
                     <TextBlock   TextWrapping="Wrap" Text="{Binding   ID}" Style="{StaticResource   PhoneTextNormalStyle}" VerticalAlignment="Center"   HorizontalAlignment="Center"/> 
                 </Border> 
                 <TextBlock   HorizontalAlignment="Left" TextWrapping="Wrap"   Text="{Binding   Name}" VerticalAlignment="Top"   Style="{StaticResource   PhoneTextSubtleStyle}" Margin="10,5,10,0"   Grid.Column="1" Foreground="Black"/> 
             </Grid> 
         </DataTemplate> 
     </phone:PhoneApplicationPage.Resources> 
     <!--LayoutRoot is the root grid where all page content is placed--> 
     <Grid   x:Name="LayoutRoot"   Background="Transparent"> 
         <Grid.RowDefinitions> 
             <RowDefinition   Height="Auto"/> 
             <RowDefinition   Height="*"/> 
         </Grid.RowDefinitions> 
         <!--TitlePanel contains the name of the application and page title--> 
         <StackPanel   Grid.Row="0" Margin="12,17,0,28"> 
             <TextBlock   Text="Product Catalog" Style="{StaticResource   PhoneTextNormalStyle}" Margin="12,0"/> 
             <TextBlock   Text="Product Catalog" Margin="9,-7,0,0"   Style="{StaticResource   PhoneTextTitle1Style}"/> 
         </StackPanel> 
         <!--ContentPanel - place additional content here--> 
         <Grid   x:Name="ContentPanel"   Grid.Row="1" Margin="12,0,12,0"> 
             <phone:LongListSelector   x:Name="ProductLongListSelector"   ItemsSource="{Binding   Products}" ItemTemplate="{StaticResource   ProductDataTemplate}"/> 
         </Grid> 
     </Grid> 
</phone:PhoneApplicationPage> | 
As the result our Product catalog application will look like below
Result
Please review the following article to learn how to quickly connect your application to Microsoft Dynamics AX 2012 Demo VM to test out the integration:    http://ax2012aifintegration.blogspot.com/2013/04/microsoft-dynamics-ax-2012-windows-8.html
In case you are developing a mobile application for production please review the best practice guidance on Developing Mobile apps for Microsoft Dynamics AX 2012 here:  http://www.microsoft.com/en-us/download/details.aspx?id=38413
Summary: This document describes how to apply MVVM (Model-View-ViewModel) architectural pattern when developing Windows Phone 8 Product catalog  sample App using XAML/C#.NET.
Tags: MVVM, Model-View-ViewModel, Windows Phone 8 App, C#.NET, XAML, Microsoft Dynamics AX 2012.
Note: This document is intended for information purposes only, presented as it is with no warranties from the author. This document may be updated with more content to better outline the concepts and describe the examples.





 
No comments:
Post a Comment