Tuesday, March 22, 2011
Sharing a ViewModel in MVVM
- Install MVVM Light V3 Binaries and Templates for your flavor of Visual Studio
http://www.galasoft.ch/mvvm/installing/manually/ - Install the WP7 RTM hotfix
http://blog.galasoft.ch/archive/2010/07/22/mvvm-light-hotfix-for-windows-phone-7-developer-tools-beta.aspx - If you did not unblock the MVVM binaries .Zip file before you installed you can either unblock that .Zip file now and reinstall (the recommend method) or individually unblock all of the installed MVVM Light binaries for WP7 and Silverlight 3.
- Create a new MvvmLight (WP7) solution with any name, in the example I named it "VMresue".
- Add a second project (File/Add/New Project...) WP7 or Silverlight. If you're creating a Silverlight project ensure that it's using Version 3 as this version is more compatable with WP7.
- Delete the contents of the "ViewModel" folder in the new project. Replace them with links to the VM of the first project. If you did it correctly you will have small "shortcut" arrow in the lower left for the linked files in the Solution Explorer.
- Adjust new projects to reference the same namespace as the first project. This requires changing App.xaml.cs's using line from "using VMinSilverlight.ViewModel;" to "using VMreuse.ViewModel;".
Labels: Multi-Project, MVVM Light, Reuse ViewModel
Wednesday, December 29, 2010
Reusing the ViewModel in MVVM for WP7
Edit: There turned out to be a way to do this without having to deal with the warning message that appears from WP7 using a Silverlight Class Library. The altertive way retains the write once ViewModel, but compiles the ViewModel seperately in each project it's used in: http://feddas.blogspot.com/2011/03/sharing-viewmodel-in-mvvm.html
I am creating a game for the WP7 that I decided I wanted to be a pay to play game. One important step that became evident is the need for a trail version. I wanted the trail version to stay up to date with minimal effort as I update the rest of the game. To do this I decided to make use of the MVVM model, using a single ViewModel for both the View of the paid version and the View of the trail version.
I thought this seperation would be a daunting task as I had little experience creating multi-project solutions. However, this is surprisingly simple. The extreme simplicity of it explains why I was unable to find much information while searching the internet. Following are the steps I took.
- Install MVVM Light V3 Binaries and Templates for your flavor of Visual Studio
http://www.galasoft.ch/mvvm/installing/manually/ - Install the WP7 RTM hotfix
http://blog.galasoft.ch/archive/2010/07/22/mvvm-light-hotfix-for-windows-phone-7-developer-tools-beta.aspx - If you did not unblock the MVVM binaries .Zip file before you installed you can either unblock that .Zip file now and reinstall (the recommend method) or individually unblock all of the installed MVVM Light binaries for WP7 and Silverlight 3.
- Create a new MvvmLight (WP7) project with any name, I named if after a game I want to create called BouncyLasersMvvm.
- Add a Silverlight Class Library named “ViewModel” that is targeted to Silverlight Version 3. I choose Silverlight 3 because it is the CLR that WP7 uses.
- Click and drag the ViewModel Folder into the ViewModel Project to create a copy.
- In the ViewModel Project Add a reference to all 3 GalaSoft MVVM libraries; "System.Windows.Interactivity.dll" "GalaSoft.MvvmLight.dll" and "GalaSoft.MvvmLight.Extras.dll"
- Delete the Model and ViewModel folders from the MVVM project and add a reference to the ViewModel project.
- In the App.xaml of the View project, change the value of xmlns:vm to
[your solution name].ViewModel;assembly=ViewModel
xmlns:vm="clr-namespace:BouncyLasersMvvm.ViewModel;assembly=ViewModel" - In the codebehind for the App.xaml, App.xaml.cs, change the last using statement, that should now have a red line beneath it, to use the same namespace you referenced in the App.xaml in step 9. In this example it would be using BouncyLasersMvvm.ViewModel
That’s it. If you’d like to create more Views add new MVVM Light projects. Then repeat steps 8 and 10. You can now make Views for trail versions or Views for demos to put on a website using silverlight.
When you modify the text used for the Welcome property inside of ViewModel/MainViewModel.cs and swap the project that is run using “Set as startup project” you will see that all the Views you create now use the same ViewModel.
Edit: Limitations of a Silverlight 3 ViewModel for WP7 (from http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/79858a29-4db0-460d-9a75-3630211a28fb/):
"You can reuse a Silverlight 3 Class Library between a web and WP7 project without any problems as long as you follow the following guidelines:
- Make sure the class library is based on Silverlight 3, not 4.
- Don't reference any Windows Phone-specific controls.
- Don't reference System.Windows.Browser (it's not in WP7).
- Don't use IQueryable as it's not in WP7.
Labels: Multi-Project, MVVM Light, Reuse ViewModel
Tuesday, December 28, 2010
Getting MVVM Light to work with WP7
The major difference is the Navigation namespace is now inside the Microsoft.Phone.Controls namespace.
Following are the steps I took to add an MVVM Light WP7 project to run.
Changes to Project References
Add reference to
Microsoft.Phone
Microsoft.Phone.Interop
remove refrence to
Microsoft.Phone.Controls.Navigation
Changes to WMAppManifest.xml
the "L" in silverlight is no longer a capital letter, Change case of RuntimeType value to
Silverlight
remove instance of
PlaceHolderString="Default task"
Changes to Permissions on .dll's
Error messages may pop up saying .dll's are flagged from being downloaded from the web.
-Navigate to the files in explore
-right click an offending file
-select properties
-on the "General" tab click "Unblock" near the bottom.
Changes to App.xaml
remove from App.xaml
xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
and
Add to App.xaml.cs
the usings
using Microsoft.Phone.Controls;
using System.Windows.Navigation;
and
public App()
{
...keep code already in there and add lines below
// Phone-specific initialization
InitializePhoneApplication();
}
#region Phone application initialization
///
/// Provides easy access to the root frame of the Phone Application.
///
///The root frame of the Phone Application.
public PhoneApplicationFrame RootFrame { get; private set; }
// Avoid double-initialization
private bool phoneApplicationInitialized = false;
// Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;
// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
// Ensure we don't initialize again
phoneApplicationInitialized = true;
}
// Do not add any additional code to this method
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;
// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
// Code to execute if a navigation fails
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// A navigation has failed; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
#endregion
Changes to MainPage.xaml
remove
xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
add
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
change phoneNavigation:PhoneApplicationPage to phone:PhoneApplicationPage on both the top of the page and the bottom
Edit: This didn't fix everything, there are issues such as the ListViewItem being replaced by the ListBoxItem. I recommend following the link Laurent Bugnion commented below, where he's already done all the work for us. If you're really curious of all the changes do a diff between the templates.
Labels: MVVM Light, MVVM Light V3, WP7
Subscribe to Posts [Atom]