In this post let’s see how we can use Shared Source Code using “Add As Link” and #if conditional blocks to design a common code base for Windows Store and Windows Phone 8 App development.
I am firing up a new instance of Visual Studio and I am creating a new project. The type of project I am going to create is “Windows Phone App”. I am naming the project as “WindowsPhone8App” and for the solution name I am giving "SharedSourceCodeDemo”. Inside the project I am creating three folders named “Model”, “ViewModel” and “Images”. I am adding some images to the “Images” folder. Inside “Model” folder I am adding a class named “PhotoItem”.
PhotoItem.cs
using System;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
namespace WindowsPhone8App.Model
{
public class PhotoItem
{
public string PhotoName { get; set; }
public BitmapImage Photo { get; set; }
public static List<PhotoItem> GetPhotos()
{
return new List<PhotoItem>()
{
new PhotoItem(){PhotoName="Image1",Photo = new BitmapImage(new Uri("/Images/Image1.jpg", UriKind.Relative))},
new PhotoItem(){PhotoName="Image2",Photo = new BitmapImage(new Uri("/Images/Image2.jpg", UriKind.Relative))},
};
}
}
}
PhotoItemViewModel.cs
using WindowsPhone8App.Model;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WindowsPhone8App.ViewModel
{
public class PhotoItemViewModel : INotifyPropertyChanged
{
private ObservableCollection<PhotoItem> photoList;
public ObservableCollection<PhotoItem> PhotoList
{get
{
return photoList;
}
set
{
photoList = value;
NotifyPropertyChanged();
}
}
public void LoadData()
{
PhotoList = new ObservableCollection<PhotoItem>(PhotoItem.GetPhotos());
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
MainPage.xaml
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<phone:LongListSelector ItemsSource="{Binding PhotoList}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding PhotoName}"></TextBlock>
<Image Source="{Binding Photo}"></Image>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
MainPage.xaml.cs
using System.Windows;
using Microsoft.Phone.Controls;
using WindowsPhone8App.ViewModel;
namespace WindowsPhone8App
{
public partial class MainPage : PhoneApplicationPage
{
PhotoItemViewModel viewModel = new PhotoItemViewModel();
public MainPage()
{
InitializeComponent();
this.Loaded += MainPage_Loaded;
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
viewModel.LoadData();
DataContext = viewModel;
}
}
}
Windows Phone 8 |
Now let’s see how we can use the above two classes in a Windows Store App and that's of course without copy and pasting the files across the projects.
I am adding a new project to the solution of type “Blank App(XAML)” under Windows Store App templates which I am naming as “WindowsStoreApp”. There I am creating three folders named “Model”, “ViewModel” and “Images”. Now I am right clicking on the Model and clicking on Add->Existing Item. I am navigating to the “WindowsPhone8App” projects’ model folder and selecting the “PhotoItem.cs”. Instead of clicking on “Add”, I am selecting “Add As Link.”
I am adding a new project to the solution of type “Blank App(XAML)” under Windows Store App templates which I am naming as “WindowsStoreApp”. There I am creating three folders named “Model”, “ViewModel” and “Images”. Now I am right clicking on the Model and clicking on Add->Existing Item. I am navigating to the “WindowsPhone8App” projects’ model folder and selecting the “PhotoItem.cs”. Instead of clicking on “Add”, I am selecting “Add As Link.”
"Add As Link" |
I am doing the same for “PhotoItemViewModel.cs” and for my Images. I am adding all these as “Add As Link” to respective folders.
Now I can see my project files in the Solution Explorer as follows.
Files added" using "Add As Link" |
Now when I open the “PhotoItem.cs” from my “WindowsStoreApp” project, I am getting some errors.
Error |
That is of course I can’t use Windows Phone 8 Assemblies inside my Windows Store Application. For that I am going to use #if conditional blocks. I can find the compilation symbol for Windows Store Apps in project properties. Inside Build tab, there it is as "NETFX_CORE". Same way you can find the compilation symbol for Windows Phone 8 apps which is "WINDOWS_PHONE"
Conditional compilation symbols |
PhotoItem.cs
using System;
using System.Collections.Generic;
#if NETFX_CORE
using Windows.UI.Xaml.Media.Imaging;
#endif
#if WINDOWS_PHONE
using System.Windows.Media.Imaging;
#endif
namespace WindowsPhone8App.Model
{
public class PhotoItem
{
public string PhotoName { get; set; }
#if NETFX_CORE
public string Photo { get; set; }
public static List<PhotoItem> GetPhotos()
{
return new List<PhotoItem>()
{
new PhotoItem(){PhotoName="Image1",Photo = "/Images/Image1.jpg"},
new PhotoItem(){PhotoName="Image2",Photo = "/Images/Image2.jpg"},
};
}
#endif
#if WINDOWS_PHONE
public BitmapImage Photo { get; set; }
public static List<PhotoItem> GetPhotos()
{
return new List<PhotoItem>()
{
new PhotoItem(){PhotoName="Image1",Photo = new BitmapImage(new Uri("/Images/Image1.jpg", UriKind.Relative))},
new PhotoItem(){PhotoName="Image2",Photo = new BitmapImage(new Uri("/Images/Image2.jpg", UriKind.Relative))},
};
}
#endif
}
}
Here I have inserted some #if conditional blocks for using statements as well as inside the class. That’s because in Windows Store App, I can’t directly bind image to a BitmapImage, instead I need to set the Image source Uri as a string. The thing to understand here is there is only one PhotoItem class, I am using #if conditional blocks to state which part I am going to use in Windows Store App and which part I am going to use in Windows Phone 8 App.
Now once this is done, I am modifying the MainPage.xaml inside my Windows Store App to bind to “PhotoItemViewModel”.
MainPage.xaml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{Binding PhotoList}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding PhotoName}"></TextBlock>
<Image Source="{Binding Photo}" Width="100" Height="100"></Image>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using WindowsPhone8App.ViewModel;
namespace WindowsStoreApp
{
public sealed partial class MainPage : Page
{
PhotoItemViewModel viewModel = new PhotoItemViewModel();
public MainPage()
{
InitializeComponent();
this.Loaded += MainPage_Loaded;
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
viewModel.LoadData();
DataContext = viewModel;
}
}
}
After completing all these steps, I am running my Windows Store App. I am getting the output as follows.
Windows Store App |
Happy Coding.
Regards,
Jaliya
No comments:
Post a Comment