Implement MVVM Pattern in Windows Phone 7 using WCF Service

This article is going to describe how to use MVVM pattern in Windows Phone 7 using a WCF service.


This article is going to describe how to use MVVM pattern in Windows Phone 7 using a WCF service.

Getting Started

Creating a Windows Phone Application:

  1. Open Visual Studio 2010.
  2. Go to File => New => Project
  3. Select Silverlight for Windows Phone from the Installed templates and choose Windows Phone Application
  4. Enter the Name and choose the location.

Click OK.

MVVMinPhone1.jpg

Image 1.

Now add a new WCF Service application using Add New Project.

MVVMinPhone2.jpg

Image 2.


MVVMinPhone3.jpg

Image 3.


Now add a class using LINQ to SQL Classes in WCF service using the Add New Item tab. And drag and drop data tables from database.

MVVMinPhone4.jpg


Image 4.


My data model looks like this.

MVVMinPhone5.jpg

Image 5.


Now start coding the WCF service. Put this code in.

EventService.svc.cs

public class EventsService : IEventsService
{
    MCDataClassesDataContext context = new MCDataClassesDataContext(); 
    public List<Post_CastingCall> GetLatestEvents()
    {                     
        var dateTime = DateTime.Now.ToString();
        var events = (from r in context.Post_CastingCalls
                //where (Convert.ToDateTime(r.Date_Expires) > DateTime.Now)
                orderby r.Date_Sent descending
                select r);
        return events.ToList(); 
    }
    public List<Post_CastingCall> GetEventByEventId(int eventId)
    {
        MCDataClassesDataContext context = new MCDataClassesDataContext();
        var eventsbyid = from p in context.Post_CastingCalls
                         where p.ID == eventId
                         select p;
        return eventsbyid.ToList();
    }
}


IEventsService.cs


[ServiceContract]
public
interface IEventsService
{
    [OperationContract]
    List<Post_CastingCall> GetLatestEvents();
    [OperationContract]
    List<Post_CastingCall> GetEventByEventId(int eventId);

}


Now build the service and you can check that the WCF service is working or not using right click and View in Browser.

MVVMinPhone6.jpg

Image 6.


When you click on given URL, it shows result in XML format like this.

MVVMinPhone7.jpg

Image 7.


We are done here with creating the service; now to work on the application. Right click on application and click Add Service Reference.

MVVMinPhone8.jpg

Image 8.

Now discover the service reference and click OK.


MVVMinPhone9.jpg

Image 9.

Now add a folder to the application; the name should be Model and add a new class in this folder and give it the name Events.cs.

Model/Events.cs

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.ComponentModel;
using
System.Collections.ObjectModel;
using
MCMobile.BindingUtilities;

namespace
MCMobile.Model
{
    public class Events : ViewModelBase
    {
        public int UserId { get; set; }
        public string _category;
        public string _title;
        public string _city;
        public string _state;
        public string _country;
        public string _zip;
        public string _description;
        public Uri _logo;

        //This property idicates event category field
        public string Category
        {
            get
            {
                return _category;
            }
            set
            {
                _category = value;
                NotifyPropertyChanged("Category");
            }
        }
        //This property idicates event title field
        public string Title
        {
            get
            {
                return _title;
            }
            set
            {
                _title = value;
                NotifyPropertyChanged("Title");
            }
        }
        //This property idicates event city field
        public string City
        {
            get
            {
                return _city;
            }
            set
            {
                _city = value;
                NotifyPropertyChanged("City");
            }
        }
        //This property idicates event state field
        public string State
        {
            get
            {
                return _state;
            }
            set
            {
                _state = value;
                NotifyPropertyChanged("State");
            }
        }
        //This property idicates event country field
        public string Country
        {
            get
            {
                return _country;
            }
            set
            {
                _country = value;
                NotifyPropertyChanged("Country");
            }
        }
        //This property idicates event zip field
        public string Zip
        {
            get
            {
                return _zip;
            }
            set
            {
                _zip = value;
                NotifyPropertyChanged("Zip");
            }
        }
        //This property idicates event description field
        public string Description
        {
            get
            {
                return _description;
            }
            set
            {
                _description = value;
                NotifyPropertyChanged("Description");
            }
        }
        //This property idicates event logo field
        public Uri Logo
        {
            get
            {
               return _logo;
            }
            set
            {
                _logo = value;
                NotifyPropertyChanged("Logo");
            }
        }
    }

}


Make another folder with the name BindingUtilities and add a class inside of that folder.

ViewModelBase.cs


using System;
using
System.Windows;
using
System.ComponentModel;
namespace
MCMobile.BindingUtilities
{
    public abstract class ViewModelBase
        : DependencyObject, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public bool IsDesignTime
        {
            get { return DesignerProperties.IsInDesignTool; }
        }
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

}


You can write this method in the Events class which I have written in comments code.

Now add a folder named ViewModel and add a class inside of that folder.

ViewModel/EventsViewModel.cs


using MCMobile.EventServiceReference;
using
System.Linq;
using
System.Collections.Generic;
using
MCMobile.BindingUtilities;
using
MCMobile.Model;
using
System.Collections.ObjectModel;
using
System.ComponentModel;
using
System.Windows.Media.Imaging;
public class EventsViewModel : ViewModelBase
    {
        //public List<Events> EventCollections{ get; set; }
        public void LoadEvents()
        {           
            EventsServiceClient eventsvc = new EventsServiceClient();
            eventsvc.GetLatestEventsCompleted += new EventHandler<GetLatestEventsCompletedEventArgs>(eventsvc_GetLatestEventsCompleted);
            eventsvc.GetLatestEventsAsync();           
        }
        void eventsvc_GetLatestEventsCompleted(object sender, GetLatestEventsCompletedEventArgs e)
        {           
            var element = e.Result;
            var events =
            from var in element
            select new Events
             {
                 UserId = Convert.ToInt32(var.UserId),
                 Title = var.Job_Title,
                 Category = var.Category.ToString(),                
                 Logo = new Uri("/MCMobile;component/Logo/" + var.UserId + "/" + "Real/" + var.Logo.ToString(), UriKind.Relative),
                 City = var.Job_City,
                 State = var.Job_State,
                 Country = var.Job_Country,
                 Zip = var.ZipCode
             };
            EventCollections = events.ToList();           
        }
        public List<Events> _collections;
        public List<Events> EventCollections
        {
            get
            {
                return _collections;
            }
            set
            {
                _collections = value;
                NotifyPropertyChanged("EventCollections");
            }
        }     

    }


Now add one more folder name View and inside of this folder add a Windows Phone user control using the Add New Item tab.

View/EventsView.xaml


<UserControl x:Class="MCMobile.View.EventsView"
    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"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    d:DesignHeight="480" d:DesignWidth="480">

   
<UserControl.Resources>       
       
<SolidColorBrush x:Key="MyBrush" Color="Green"/>
       
<Style TargetType="Border" x:Key="PageBackground">
           
<Setter Property="Background" Value="black"/>
       
</Style>
       
<Style TargetType="TextBlock" x:Key="HeaderBoldText">
           
<Setter Property="Foreground" Value="Green"></Setter>
           
<Setter Property="FontWeight" Value="Bold"></Setter>
           
<Setter Property="FontFamily" Value="Verdana"></Setter>
           
<Setter Property="FontSize" Value="24"></Setter>
       
</Style>
       
<Style TargetType="TextBlock" x:Key="TitleText">
           
<Setter Property="FontSize" Value="14"/>
           
<Setter Property="Foreground" Value="#4E87D4"/>
           
<Setter Property="FontFamily" Value="Tahoma"/>
           
<Setter Property="Margin" Value="0,40,10,10"/>
           
<Setter Property="Width" Value="300"></Setter>
       
</Style>
       
<Style TargetType="TextBlock" x:Key="Label">
           
<Setter Property="FontSize" Value="8"/>
           
<Setter Property="Foreground" Value="{StaticResource MyBrush}"/>
           
<Setter Property="FontFamily" Value="Arial"/>
           
<Setter Property="FontWeight" Value="Bold"/>
           
<Setter Property="Margin" Value="0,3,10,0"/>
           
<Setter Property="Width" Value="100"></Setter>
           
<Setter Property="Height" Value="20"></Setter>
       
</Style>
   
</UserControl.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 x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
           
<TextBlock x:Name="ApplicationTitle" Text="Latest Events" Style="{StaticResource HeaderBoldText}"/>
           
<!--<TextBlock x:Name="PageTitle" Text="Events" 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">
           
<Grid.RowDefinitions>
               
<RowDefinition Height="*"/>
               
<RowDefinition Height="Auto"/>
           
</Grid.RowDefinitions>
           
<Grid.ColumnDefinitions>
               
<ColumnDefinition />
           
</Grid.ColumnDefinitions>
           
<ListBox Height="664" HorizontalAlignment="Left"
                     Margin="14,14,0,0"
                     Name="eventsListBox"
                     VerticalAlignment="Top"
                     ItemsSource="{Binding Path=EventCollections}"
                     Width="432">

               
<ListBox.ItemTemplate>
                   
<DataTemplate>
                       
<StackPanel Orientation="Horizontal" Margin="0,0,8,0">
                           
<Image Source="{Binding Logo}" Width="150" HorizontalAlignment="Center" ></Image>
                           
<StackPanel Width="370" Margin="5,0,0,0">
                               
<TextBlock Text="{Binding Title}" Style="{StaticResource HeaderBoldText}"  />
                               
<TextBlock Text="{Binding City}" />
                               
<TextBlock Text="{Binding State}" />
                               
<TextBlock Text="{Binding Country}" />
                           
</StackPanel>
                       
</StackPanel>
                   
</DataTemplate>
               
</ListBox.ItemTemplate>
           
</ListBox>
       
</Grid>
   
</Grid>
</
UserControl
>

MVVMinPhone10.jpg

Image 10.

Now add a new Windows Phone Portrait Page in the root application. And add namespace of view folder.

EventsPage.xaml


<phone:PhoneApplicationPage
    x:Class="MCMobile.EventsPage"
    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" d:DesignHeight="768" d:DesignWidth="480"

    xmlns:views="clr-namespace:MCMobile.View"

    shell:SystemTray.IsVisible="True">

   
<!--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 x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
           
<views:HeaderView x:Name="headerView"></views:HeaderView>
       
</StackPanel>
       
<!--ContentPanel - place additional content here-->
       
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
           
<views:EventsView x:Name="eventsView"></views:EventsView>

       
</Grid>
   
</Grid>
   
</
phone:PhoneApplicationPage>

EventsPage.xaml.cs


using MCMobile.EventViewModelNamespace;
public
partial class EventsPage : PhoneApplicationPage
{
    public EventsPage()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(EventsPage_Loaded);
    }
    void EventsPage_Loaded(object sender, RoutedEventArgs e)
    {
        EventsViewModel EmployeeViewModel = new EventsViewModel();
        EmployeeViewModel.LoadEvents();
        eventsView.DataContext = EmployeeViewModel;
        //GetEvents();
    }
    private ImageSource GetImage(string fileName)
   {
        return new BitmapImage(new Uri(fileName, UriKind.Relative));
    }

}


Now it is time to build and run the application to see the output.


MVVMinPhone11.jpg

Image 11.


Conclusion

So we are done here with MVVM pattern in Windows Phone using WCF service. If you have questions or comments then drop me a line in the comments section.