Wednesday, August 07, 2013

Portable Class Library Projects and MVVM Light

With Portable Class Library Projects you can create a single library that can target different platforms (e.g. Windows Phone, .Net, Windows Store Apps). For most of the modern apps it’s kind of mandatory to use the MVVM pattern, a famous MVVM library is Laurent Bugnion MVVM Light library. In this post we will walk through the steps needed to create a Portable Class Library that uses the MVVM Light library and targets the Windows Phone 8 and .Net for Windows Store Apps frameworks.

I will be using Visual Studio 2012 with Update 3.

- Let’s create a new Portable Class Library project and name it MyApp.Core, the solution name will be MyApp

1

- We will target the Windows Phone 8 and .Net for Windows Store Apps

image

- We will create two applications, the first is a Windows Store Blank Application named MyApp.Win8

3

and the second is a Windows Phone 8 named MyApp.WP8

4

- We will add a reference to the Portable Class Library Project MyApp.Core to the Windows Store Project and the Windows Phone 8 project

- The MyApp.Core portable project will contain our model and our view model and will be shared by the Windows Store application and the Windows Phone 8 application, we will use the MVVM Light library to do this. We need to add this library to the MyApp.Core project.

- To do that right click the MyApp.Core project in the solution explorer, and choose Manage NuGet Packages

image

- Search for Portable MVVMLight package and click install to add it to the project, when prompted accept the license

image

- The next step is to add references to the MVVMLight library to the Windows Store project and the Windows Phone 8 project. the trick is to add the corresponding version of the MVVMLight library to each project. Right click on the solution node in the solution explorer tool window and choose Open Folder in File Explorer

image

- In the solution folder you will a folder named packages, this folder was created when we added the NuGet package for MVVMLight library, it contains  all of the MVVMLight library DLLs for the different frameworks. There are two DLLs that we need GalaSoft.MvvmLight.dll and Microsoft.Practices.ServiceLocation.dll.

For the Windows Store project we will use the DLLs available in the following locations

C:\SOLUTION FOLDER\packages\Portable.MvvmLightLibs.4.1.27.6\lib\portable-net45+sl4+wp71+win8\GalaSoft.MvvmLight.dll

C:\SOLUTION FOLDER\packages\Portable.CommonServiceLocator.1.2.2\lib\portable-net4+sl4+wp7+win8\Microsoft.Practices.ServiceLocation.dll

For the Windows Phone 8 we will use the DLLs available in the following locations

C:\SOLUTION FOLDER\packages\Portable.MvvmLightLibs.4.1.27.6\lib\wp8\GalaSoft.MvvmLight.dll

C:\SOLUTION FOLDER\packages\Portable.CommonServiceLocator.1.2.2\lib\portable-net4+sl4+wp7+win8\Microsoft.Practices.ServiceLocation.dll

- In the MyApp.Core project we will create our view model to be used by the two apps. First we will create a view model locator class that will be used as the main repository for all the view models we have, in our sample we will have one view model only called MainViewModel

public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>();
}

public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}

}


For the sake of simplicity the MainViewModel class will have one property that contains a hardcoded list of strings, in real world applications this class should expose all of your model data as well as other required UI functionalities such as commands



public class MainViewModel
{
List<string> _sampledata = new List<string>();

public MainViewModel()
{
_sampledata.Add("Item1");
_sampledata.Add("Item2");
_sampledata.Add("Item3");
_sampledata.Add("Item4");
_sampledata.Add("Item5");
}
public List<string> Data
{
get {
return _sampledata;
}
private set { }
}
}


- To use the view models from the application projects, first we need to create an instance of the ViewModelLocator class, in the windows store project we will define an instance of the ViewModelLocator as a resource in the App.xaml file



<Application
x:Class="MyApp.Win8.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp.Win8"
xmlns:vm="using:MyApp.Core">
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" />
<ResourceDictionary.MergedDictionaries>
<!--
Styles that define common aspects of the platform look and feel
Required by Visual Studio project and item templates
-->
<ResourceDictionary Source="Common/StandardStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>

</ResourceDictionary>
</Application.Resources>
</Application>


we will do the same for the windows phone 8 project



<Application
x:Class="MyApp.WP8.App"
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:vm="clr-namespace:MyApp.Core;assembly=MyApp.Core">
<Application.Resources>
<local:LocalizedStrings xmlns:local="clr-namespace:MyApp.WP8" x:Key="LocalizedStrings"/>
<vm:ViewModelLocator x:Key="Locator" />
</Application.Resources>
<Application.ApplicationLifetimeObjects>
<shell:PhoneApplicationService
Launching="Application_Launching" Closing="Application_Closing"
Activated="Application_Activated" Deactivated="Application_Deactivated"/>
</Application.ApplicationLifetimeObjects>
</Application>


- For the windows phone 8 UI, in the MainPage.xaml, we will set the data context of the page to the Main property of the ViewModelLocator class



image






- we will add a list box and bind its ItemsSource property to the Data of th MainViewModel class



image



- For the windows store project, we will also set the data context of the page to the Main property of the ViewModelLocator class, and we will add a list box and bind its ItemsSource property to the Data of th MainViewModel class



image







- Now we are done, we have a Portable Class Library that contains our view models and that is shared by the windows phone 8 and the windows store app project



The Windows Phone 8 Application



The Windows Store Application

Sunday, May 19, 2013

Thursday, February 21, 2013

Monday, March 26, 2012

DevLifeStyle March 2012 Event: Sessions Recordings

Here are the sessions recordings for our last event

Building High Performance Applications with .NET 4.5: Part1, Part2

Kinect for Windows

Developing Applications for Windows 8

Sunday, January 29, 2012

Windows 8 Session

In our next DevLifeStyle Community event I will be presenting a session on Windows 8. you can register here

http://dlsfeb2012.eventbrite.com/

Tuesday, September 27, 2011

Silverlight 5 P-Invoke: Using Kinect SDK from Silverlight

Away from all the discussions about whether Silverlight is dead or not, The Silverlight 5 RC contains the previously announced P-Invoke feature which enables you to call Win32 style APIs from a trusted Silverlight application.

There are some attempts to use Kinect from Silverlight (here) but this was before MS released the official SDK. we will use Silverlight 5 P-Invoke feature to call the Kinect SDK APIs.

P-Invoke in Silverlight works just like P-Invoke on the desktop. you use the DllImport attribute to import the APIs and you declare in your code the dependent types (Enums, structs, etc.)

  1. [DllImport("MSRKINECTNUI.DLL")]
  2.       private static extern HRESULT NuiInitialize(uint dwFlags);

I tried to keep the classes and methods in library identical to the ones in the official SDK. I implemented only a couple of the available APIs (with the help of the Coding4Fun Kinect Toolkit and Reflector).

To test the library we will create a simple application:

- Create a new Silverlight 5 application

- Add a reference to the KinectSilverlightLibrary.

- Change the properties of the project: enable running out of browser.

Enable running out of browser

- Change the Out-of-Browser settings to require elevated trust

Require elevated trust

- In the App.xaml.cs file, define a new property of type Runtime, this property represents the Kinect runtime, in the Application_Startup event handler initialize the runtime and in the Application_Exit event handler shut down the runtime

  1. Runtime kinectRuntime = new Runtime();
  2. public Runtime KinectRuntime
  3. {
  4.     get
  5.     { return kinectRuntime; }
  6. }
  7. private void Application_Startup(object sender, StartupEventArgs e)
  8. {
  9.     this.RootVisual = new MainPage();
  10.     kinectRuntime.Initialize(RuntimeOptions.UseColor | RuntimeOptions.UseDepth );
  11. }
  12. private void Application_Exit(object sender, EventArgs e)
  13. {
  14.     kinectRuntime.Uninitialize();
  15. }

- In the MainPage.xaml file add two image controls that we will use to display the video and depth streams coming from Kinect

  1. <Grid x:Name="LayoutRoot" Background="White" Loaded="LayoutRoot_Loaded">
  2.         <Grid.ColumnDefinitions>
  3.             <ColumnDefinition/>
  4.             <ColumnDefinition/>
  5.         </Grid.ColumnDefinitions>
  6.         <Image Name="image1" Stretch="Fill" Grid.Column="0" />
  7.         <Image Name="image2" Stretch="Fill" Grid.Column="1" />
  8.     </Grid>

- In the MainPage.xaml.cs add the following lines of code

  1. private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
  2.         {
  3.            Runtime runtime = (App.Current as App).KinectRuntime;
  4.            runtime.VideoStream.OpenStream(ImageType.Color, ImageResolution.Resolution640x480);
  5.           runtime.DepthStream.OpenStream(ImageType.Depth, ImageResolution.Resolution320x240);
  6.          runtime.VideoFrameReady += new EventHandler<ImageFrameReadyEventArgs>(runtime_VideoFrameReady);
  7.            runtime.DepthFrameReady += new EventHandler<ImageFrameReadyEventArgs>(runtime_DepthFrameReady);
  8.         }
  9.     
  10.         void runtime_VideoFrameReady(object sender, ImageFrameReadyEventArgs e)
  11.         {
  12.             Dispatcher.BeginInvoke(() => {
  13.                 image1.Source = e.ImageFrame.ToBitmapSource();
  14.             });
  15.         }
  16.         void runtime_DepthFrameReady(object sender, ImageFrameReadyEventArgs e)
  17.         {
  18.             Dispatcher.BeginInvoke(() =>
  19.             {
  20.                 image2.Source = e.ImageFrame.ToBitmapSource();
  21.             });
  22.  
  23.         }

When the page is loaded we open the video and depth streams and subscribe to the VideoFrameReady and DepthFrameReady events, in the event handler we retrieve the ImageFrame and convert it to a bitmap (I used the WritableBitmapEx library)

Here’s the application running

Kinect Video and Depth Streams 

You are free to continue adding the rest of the APIs to this library.

You can download the source code from here:

Tuesday, July 12, 2011

Surface 2.0 SDK Released

The long awaited Surface 2.0 SDK has been just released. to get started go to the new Surface Developer Center and download the SDK.

Once downloaded and installed, start VS2010, you will find the Surface 2.0 project templates available

Surface 2.0 Project Templates

Let’s create a sample application, I will create a simple twitter client (hopefully before scottgu creates it) let’s name it TwittSurf

Once we created the project you will have the same project structure as you have in the Surface 1.0 version, let’s create our UI

<s:SurfaceWindow x:Class="TwittSurf.SurfaceWindow1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:s="http://schemas.microsoft.com/surface/2008"
    Title="TwittSurf"
    Loaded="SurfaceWindow_Loaded" >
    <Grid>
        <s:ScatterView>
               <s:ScatterViewItem Width="400" Height="500" CanMove="True" CanScale="True" CanRotate="True" >
                  <s:SurfaceListBox x:Name="tweetsList" >
                    <s:SurfaceListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Margin="20" >
                                <Image HorizontalAlignment="Left" Source="{Binding ProfileImageLocation}"/>
                                <TextBlock Text="{Binding FromUserScreenName}"/>
                                <TextBlock Text="{Binding Text}"/>
                            </StackPanel>
                        </DataTemplate>
                    </s:SurfaceListBox.ItemTemplate>
                </s:SurfaceListBox>

            </s:ScatterViewItem>
        </s:ScatterView>
    </Grid>
</s:SurfaceWindow>

We will add a ScatterView control, inside it we will add a SurfaceListBox and configure its ItemDataTemplate.

In the Loaded event of the Window we will write our code, I will use the Twitterizer .net Library (download the lite version) to save some time, the code below will submit a query to twitter and display the result in the list box

private void SurfaceWindow_Loaded(object sender, RoutedEventArgs e)
        {
            TwitterResponse<TwitterSearchResultCollection> searchResult = TwitterSearch.Search("mosallem", null);
            tweetsList.ItemsSource = searchResult.ResponseObject;
        }

Before you run the application Open the Input Simulator (Start Menu-> Programs-> Microsoft Surface 2.0 SDK-> Tools) this tool is used to simulate the different types of inputs (finger, blob, tag).

Run the application, the list will appear with the search results, select the finger input from the input simulator, press and hold the left mouse button to simulate a finger contact on the Surface.

You can drag/rotate the list box around, to scale the list you need two fingers, you can do this by pressing/holding the left mouse button on one corner of the list, then pressing the right mouse button to keep the finger contact in this location, then you can add another finger contact on another corner by clicking the left mouse button and when you move the second finger the list will scale.

I believe you can also simulate more than one contact by connecting additional mice, but unfortunately that didn’t work for me.

bb

You can download the code from here

I’m very excited to have the SDK, Definitely I’m be spending more time playing with it. 

Monday, July 11, 2011

Portable Library Tools

With the introduction of Windows Phone 7.0 a new opportunity emerged for Silverlight developers, this new platform uses Silverlight (a version of Silverlight 3.0) as the main framework to build applications on the phone. When building applications for Silverlight and WP7 you will find that you can reuse some of the code across the two platforms, Linked source files were used to share code between WP7 and Silverlight projects along with the use of compilation directives.

Microsoft introduced a new way to create code that targets multiple platforms, it’s a Visual Studio Add-In called Portable Library Tools (Available here)

Portable Library Tools is a new Visual Studio add-in from Microsoft that enables you to create C# and Visual Basic libraries that run on a variety of .NET-based platforms without recompilation.

In this post we are going to build a sample application for WP7 and Silverlight that uses the Portable Class Library Tools.

We will create a CustomersExplorer application that will allow the user to display and edit the customers from the AdventureWorks database, Let’s start by creating new solution we will add a web application project called CustomersExplorer.Web, in this project we will have an Entity Framework model that exposes the customers in the AdventureWorks database (the EF model will use ADO.NET self tracking entities), we will expose the model through a WCF service that uses webHttpBinding. the service code is shown below

[ServiceContract]
    public interface ICustomerService
    {
           [OperationContract]
          List<Customer> GetCustomers();
           [OperationContract]
          OperationStatus SaveCustomer(Customer customer);

           [OperationContract]
          Customer GetCustomer(int custID);
    }
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class CustomerService : ICustomerService
    {
        public List<Customer> GetCustomers()
        {
            return new CustomerRepository().GetCustomers();
        }

        public OperationStatus SaveCustomer(Customer customer)
        {
            return new CustomerRepository().SaveCustomer(customer);
        }

        public Customer GetCustomer(int custID)
        {
            return new CustomerRepository().GetCustomer(custID);
        }
    }

We will add three more projects to the solution:

1. CustomersExplorer.Core: a Portable Class Library Project that will contain the shared code to be used in the Silverlight and windows phone apps

Portable Class Library Project

2. CustomersExplorer.Silverlight: the Silverlight application

3. CustomersExplorer.WP: the windows phone 7 application

The layout of the solution should be like the following

Solution Layout

The CustomersExplorer.Core project will be used by the Silverlight and the Windows Phone applications, so we will add a reference to this project to the Silverlight and Windows Phone Projects.

Next we’ll change the settings of the CustomersExplorer.Core

project. By default when you create a new Portable Class Library project its settings is set to target the .Net 4.0, Silverlight 4.0 and Windows Phone 7.0 frameworks, we will change this to target Silverlight and Windows Phone. Go to the properties of the project and click Change button in the target frameworks section

Portable Class Library Project Target Frameworks

In the dialog, choose Windows Phone 7.0 and Silverlight 4.0

Target Frameworks

We need to add a reference to the System.Windows assembly, this assembly contains the ObservableCollection type that we need in the Silverlight and WP applications, the dll is located in this path “C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\” 

Next we need to add a service reference for the CustomersService, for some unknown reason If you tried to add a reference to the Customers service in the Portal Class Library project, the generated proxy class will not use ObservableCollection as the collection type, so we will use the SLsvcutil tool to create the proxy class, the slsvcutil tool is located in the folder C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Tools”

Run the tool with the following command line

  1. slsvcutil  /edb /namespace:"*,CustomerExplorer.Core.CustomersService" /ct:System.Collections.ObjectModel.ObservableCollection`1 /r:"C:\PROGRAM FILES (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\System.Windows.dll" /directory:C:\Users\Mohamed\Desktop\generated\

Take the generated file CustomerService.cs and add it to the CustomersExplorer.Core project, the other generated file (ServiceReferences.ClientConfig) must be copied to the 

CustomersExplorer.Silverlight and CustomersExplorer.WP projects.

In the CustomersExplorer.Core project we will create the CustomersViewModel, which exposes a property Customers of type ObservableCollection<Customer> , and a property CurrentCustomer of type Customer, two commands are exposed UpdateCustomerCommand and DeleteCustomerCommand that forward these actions to the Customers WCF service.

#region "Commands"
        public RelayCommand UpdateCustomerCommand
        {
            get;
            private set;
        }

        public RelayCommand DeleteCustomerCommand
        {
            get;
            private set;
        }
        #endregion
        
        #region "Properties"
        public const string CustomersPropertyName = "Customers";
        private ObservableCollection<Customer> _customers = null;
        public ObservableCollection<Customer> Customers
        {
            get
            {
                return _customers;
            }
            set
            {
                if (_customers == value)
                {
                    return;
                }
                 _customers = value;
                RaisePropertyChanged(CustomersPropertyName);
            }
        }


        public const string CurrentCustomerPropertyName = "CurrentCustomer";
        private Customer _currentCustomer = null;
        public Customer CurrentCustomer
        {
            get
            {
                return _currentCustomer;
            }

            set
            {
                if (_currentCustomer == value)
                {
                    _statusMessage = "";
                    return;
                }
                _currentCustomer = value;
                RaisePropertyChanged(CurrentCustomerPropertyName);
                UpdateCustomerCommand.RaiseCanExecuteChanged();
                DeleteCustomerCommand.RaiseCanExecuteChanged();
            }
        }


        public const string StatusMessagePropertyName = "StatusMessage";
        private string _statusMessage = "";
        public string StatusMessage
        {
            get
            {
                return _statusMessage;
            }

            set
            {
                if (_statusMessage == value)
                {
                    return;
                }
                _statusMessage = value;
                RaisePropertyChanged(StatusMessagePropertyName);
            }
        }
        #endregion

The Silverlight application is very simple, it has a single page with no code behind, the page creates an instance of the view model

<UserControl.Resources>
        <ViewModels:CustomersViewModel x:Key="ViewModel"/>
    </UserControl.Resources>

The main grid DataContext property is bound to the View model

<Grid x:Name="LayoutRoot" Background="White"
          DataContext="{Binding Source={StaticResource ViewModel}}" >

A combo box is used to display the customers

<ComboBox Height="23" HorizontalAlignment="Left" Margin="158,88,0,0" Name="CustomersComboBox"
                  VerticalAlignment="Top" Width="173" DisplayMemberPath="FullName"
                  ItemsSource="{Binding Path=Customers}"
                  SelectedItem="{Binding Path=CurrentCustomer, Mode=TwoWay}" />

and a bunch of Text Boxes are used to display the details of the view model CurrentCustomer property

<TextBox Height="23" HorizontalAlignment="Left" Margin="158,225,0,0" VerticalAlignment="Top" Width="219" Text="{Binding CurrentCustomer.FirstName, Mode=TwoWay}" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="158,270,0,0" VerticalAlignment="Top" Width="219" Text="{Binding CurrentCustomer.LastName, Mode=TwoWay}" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="158,316,0,0" VerticalAlignment="Top" Width="219" Text="{Binding CurrentCustomer.CompanyName, Mode=TwoWay}"/>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="158,366,0,0" VerticalAlignment="Top" Width="219" Text="{Binding CurrentCustomer.EmailAddress, Mode=TwoWay}" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="158,416,0,0" VerticalAlignment="Top" Width="219" Text="{Binding CurrentCustomer.EmailAddress, Mode=TwoWay}" />

Two buttons “Delete” and “Updated” are bound to the view model DeleteCusotmer and UpdateCustomer commands

<Button Content="Update" Height="23" HorizontalAlignment="Left" Margin="51,480,0,0" Name="UpdateButton" VerticalAlignment="Top" Width="75"
                Command="{Binding Path=UpdateCustomerCommand}" />
        <Button Content="Delete" Height="23" HorizontalAlignment="Left" Margin="158,480,0,0" Name="DeleteButton" VerticalAlignment="Top" Width="75"
                Command="{Binding Path=DeleteCustomerCommand}" />

In the Windows Phone 7 project the View Model is defined in the application resources, cause we will have two pages that use the same view model. The first page has a list box that is bound to the view model Customers property

<ListBox Name="customersList" ItemsSource="{Binding Customers}"
                      SelectedItem="{Binding Path=CurrentCustomer, Mode=TwoWay}"
                     SelectionChanged="customersList_SelectionChanged" >
                <ListBox.ItemTemplate>
                    <DataTemplate >
                        <TextBlock Text="{Binding FullName}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

The second page displays the details of the CurrentCustomer

<StackPanel x:Name="ContentPanel" >
                <TextBlock Text="CustomerID:"/>
                <TextBlock Name="CustomerIDTextBlock" Text="{Binding CurrentCustomer.CustomerID}" />
                <TextBlock Text="First Name:"/>
                <TextBox Text="{Binding CurrentCustomer.FirstName, Mode=TwoWay}" />
                <TextBlock Text="Last Name:"/>
                <TextBox Text="{Binding CurrentCustomer.LastName, Mode=TwoWay}" />
                <TextBlock Text="Company Name:"/>
                <TextBox Text="{Binding CurrentCustomer.CompanyName, Mode=TwoWay}"/>
                <TextBlock Text="Email:"/>
                <TextBox Text="{Binding CurrentCustomer.EmailAddress, Mode=TwoWay}" />
                <TextBlock Text="Phone:"/>
                <TextBox Text="{Binding CurrentCustomer.Phone, Mode=TwoWay}" />
                <StackPanel Orientation="Horizontal">
                      <Button Content="Update" Name="UpdateButton"
                cmd:ButtonBaseExtensions.Command="{Binding UpdateCustomerCommand}"/>
                    <Button Content="Delete" Name="DeleteButton"
                cmd:ButtonBaseExtensions.Command="{Binding DeleteCustomerCommand}" />
                </StackPanel>

Here are some screen shots of the running applications

CustomersExplorer.Silverlight 

Customers List Customer Details

You can download the source code from here