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,
 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:

 <local:RunningApplicationService />

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.


MVVM, Sample Data and Blend

Part 1: Divide and Conquer

In this series of posts, I’m planning to address the use of Expression Blend and Sample Data when used in an MVVM-based Silverlight project. The aim is to provide a useful mechanism for both developers and designers to be able to work on a project together, without one having to depend too much on the other.

First, a little background information.

I’ve been working on Silverlight projects pretty much solidly for the last couple of years now (since Silverlight 2 beta time) and have been using the MVVM approach for the last few projects (since we moved to SL3).

The team I work in has the benefit of having a couple of full-time designers in it (although I can create a UI, I’m a long way from being a designer). The designers spend nearly all of their time using Blend, whereas myself and the other developers spend most of our time in Visual Studio.

Since adopting MVVM for our projects, it has made it easier to separate the UI from the code, but there have still been a few difficulties:

  • At the start of the project, the designers can see everything in the solution, but the further along the project gets, the more problems they have had with getting everything to render. This is mostly due to the increased dependency on bindings as the views develop.
  • The designers use very different machines to the developers – developers have SQL Server installed, run IIS and have it all configured so that the Silverlight apps can access the appropriate services; designers have none of those tools and shouldn’t need to be concerned about things like the service or configuring IIS on their machine
  • We had to produce a rather convoluted solution to get around the above point

What do I mean by ‘convoluted’? How about this:

  • A designer-specific solution that includes the .Web project and any projects that contain Silverlight controls
  • A developer-specific solution that uses Post-Build Events to copy the .dll files generated by any Silverlight class libraries into a common folder for the Silverlight control projects to use
  • Multiple test pages, with some code-behind to specify whether you’re using the app as a developer or designer
  • A whole project dedicated to providing data for the designers so that when they run the application by pressing F5 in Blend they can see something

Now, there are approaches to solving these problems (using the design DataContext for example) but none of the solutions we saw fixed 100% of the issues.

For quite a while now the designers and myself have been discussing the matter and trying to work out how to fix all of this. Fortunately for us, a few people have blogged about ways that help achieve our goal. The main work came about because of John Papa’s ViewModelLocator pattern and Jeremy Likness’ blog about IApplicationService.

I had already been looking into MEF (used in John Papa’s VMLocator and the subject of many posts on Jeremy Likness’ blog) and so I set about working out how to achieve the following:

  1. Use Blend’s Sample Data facility when in Design mode (either VS or Blend)
  2. When you run the application (press F5) from Blend, you use the Sample Data created in Blend
  3. When you run the application from Visual Studio, you can either use the Blend Sample Data or run using the WCF service to populate values
  4. Remove the dependency on having a DesignTestPage and DevTestPage
  5. Allow the designers to modify the Sample Data themselves

I still like having the separation of projects for the designers and developers, and I know that the designers like it too.

That’s enough background for now. My next post will be on detecting whether you’re running from within Blend or Visual Studio (or indeed deployed on an IIS server)

Hello world!

This is my first blog post. I hope to be posting many Silverlight and windows development stories and tips here in the future