Just another WordPress.com weblog

MVVM, Sample Data and Blend… Continued

Part 2: Detecting where you’re running from

This is the second part of a series of posts discussing an alternative method of using Blend Sample Data to provide the appropriate data for a design-time view but with support for seeing this data at runtime when desired.

Although the Sample Data mechanisms provided by Blend greatly simplify creating data that is visible at design-time, there is a drawback, a Catch-22 if you will: you can create a sample data source that will allow you to use it at runtime from Blend, but if you want the desgin-time datacontext to be visible at runtime, it will become the datacontext, but when you replace the datacontext with a viewmodel that populates the bindings from a service method call, if you don’t have access to that service then the bindings will not populate and the data only becomes visible at design-time again.

So these posts are designed to provide a mechanism for allowing designers to see the sample data they create in Blend when they run the solution, and allow the developers to see the data returned by the service when they run the solution.

The first part of this is working out where the solution is being run from. If you just want to see the solution to the problem, you can skip straight to the code section. If you want to find out why it works, carry on reading.

After a little bit of experimenting with both Visual Studio and Blend, I discovered a few things. Let’s assume that we create a very simple MVVM:

  • In Visual Studio, create a new Silverlight Application solution. Let’s call it RunningApplicationDemo
  • When prompted to see if you want a web project for it, keep everything as it is. This should include a new project by the name of RunningApplicationDemo.Web. Then click OK.
  • When everything is created and ready for you, open the properties for the .Web project and click the Web tab
  • Leave the Start Action section alone, but (for the sake of this post) take note of what port number has been assigned. For my solution it’s 52719
  • Change the Virtual Path property to ‘/RunningApplication’
  • Go into the MainPage.xaml and add a textbox just so that you can tell the application is running fine when you press F5
  • Press F5 to run the application
  • You should see your browser open up and the URL should be something like http://localhost:52719/RunningApplication/RunningApplicationDemoTestPage.aspx

Now try opening the same project in Blend and running from there. What URL do you see? I get http://localhost:52783/RunningApplicationDemoTestPage.aspx

So, not only has the port number changed, but Blend has disregarded the virtual path too. This is good for us as it means we now have a way to tell if you’re running from Blend or not. If you set a virtual path, and it gets ignored, then you must be running from Blend. Simple.

Doing all this programmatically

As mentioned in my previous post, I came across the IApplicationService on Jeremy Likness’ blog and could see its use here.
Implementing this would allow me to create a helper that would be reusable in all future projects.

 public enum RunningApplicationType
 {
 Default = 0,
 Blend,
 VisualStudio
 }
 public class RunningApplicationService : IApplicationService
 {
 public static RunningApplicationService Current { get; set; }
 public RunningApplicationType LaunchingApplication { get; set; }

 public void StartService(ApplicationServiceContext context)
 {
 Current = this;
 // to determine if we're running from Blend, we need to know the url for where we are
 string hostUri = HtmlPage.Document.DocumentUri.AbsolutePath;
 // set a default value
 LaunchingApplication = RunningApplicationType.Default;
 // Blend always starts with the page at the root level. The port > 1000 is to check for deployment status
 if (hostUri.LastIndexOf('/').Equals(0) && HtmlPage.Document.DocumentUri.Port > 1000)
 LaunchingApplication = RunningApplicationType.Blend;
 // Visual Studio honours the path
 else if (hostUri.LastIndexOf('/') > 0 && HtmlPage.Document.DocumentUri.Port > 1000)
 LaunchingApplication = RunningApplicationType.VisualStudio;
 }
 public void StopService() { }
 }

 


With this in place, all you need to do is add it to your App.xaml file:


<code><Application.ApplicationLifetimeObjects>
 <local:RunningApplicationService />
 </Application.ApplicationLifetimeObjects></code>

Then whenever you need access to the service to do something dependent on where you run from, you can access it by using the following:

 if ((Application.Current.ApplicationLifetimeObjects[0] as RunningApplicationService).LaunchingApp == RunningApplicationType.Blend)
 // design-only work

Although this covers how to determine whether you’re running from Blend or not, it still doesn’t deal with how to provide the design-time sample data at runtime when required, so in the next post I’ll be writing about the viewmodel locator pattern and how it achieves that.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s