Mobile Corner

Disabling Design Time Data in a Windows Phone Application

How to disable Expression Blend design time data at runtime.

In the previous article, I discussed creating and working with Expression Blend design time data in Windows Phone applications. I'm going to continue this theme by covering how to effectively disable this data at run time. The important thing to remember is that you want to preserve the design time experience so that the designer can continue to use Expression Blend.

Before you start making changes, note a few points when opening the application in Visual Studio.

  • The MockDataSource.xaml listing from the previous article shows that its Build Action is set to Page (select one in Solution Explorer and look at the Properties window). This is the same action as any of the actual pages within your application, and means that the contents of the XAML file will be available to the application at run time.
  • The Build Action is set to Resource for the images added to the application. This means the images are being compiled into the main assembly for your application.
  • If you look in \Bin\Debug (assuming you've built the application using the Debug build configuration), you'll see that the main assembly is approximately 382KB in size. This is relatively large for an application that doesn't currently do anything. If you were to open the assembly in a tool like ILSpy, you'll see that the design time images have been added to this assembly, which adds considerably to its size.
  • The Build Action for MockDataSource.xaml.cs is set to Compile, which means that the class hierarchy Expression Blend created for the design time data is available to your application, adding unnecessary classes. These classes can also be seen using a tool like ILSpy.

To remove the design time data, you first need to return to Expression Blend. Click the Data source options icon on the first MockDataSource node in the Data window, and uncheck the "Enable When Running Application" option, as shown in Figure 1.


[Click on image for larger view.]
Figure 1. Uncheck "Enable When Running Application" to remove design time data.

Returning to Visual Studio, you'll now see that the Build Action property for the design time images, MockDataSource.xaml and MockDataSource.xsd has changed to DesignTimeOnly. Since the images and actual design time data aren't included in the application at runtime, you'll notice that the size of the primary assembly has dropped significantly -- to around 13KB.

Less obvious is that the Build Action for MockDataSource.xaml.cs is still set to Compile, which means you'll still see the design time classes appear in your application. Close to the top of the MockDataSource.xaml.cs file is the following comment:

// To significantly reduce the sample data footprint in your  production application, you can set
// the DISABLE_SAMPLE_DATA conditional compilation constant and  disable sample data at runtime.

This suggests that by specifying the DISABLE_SAMPLE_DATA, the design time classes won't be compiled. Bring up the project properties and you can add this compilation constant via the Build tab. In Figure 2, we're only making this change in the Release configuration.


[Click on image for larger view.]
Figure 2. Adding the compilation constant.
After making this change, the application should build successfully. However, when you go to run the application you'll see an exception complaining that the constructor for the MockDataSource class doesn't exist. The only workaround for this is to either remove the compilation constant or to remove the following line from the App.xaml that creates the instance of the design time data:

<SampleData:MockDataSource x:Key="MockDataSource"  d:IsDataSource="True"/>

Clearly, neither of these options are appropriate; the former leaves the design time classes in your application, the latter will completely remove the design time data so that it's no longer available in the designer experience. In fact, if you remove the MockDataSource line from the App.xaml, you'll see a number of warning messages appear in the Results and Data windows in Expression Blend.

The crux of the issue is that you essentially need two different App.xaml files: one that includes the design time data and one that doesn't. The first should be compiled and used only at design time; the second should be compiled and used at run time.

This can be achieved by making a slight modification to the project file (DesignTimeDataSample.csproj) to tell MSBuild (the underlying build system for Visual Studio) which file to use, depending on which build configuration is specified.

Before making this change, you need to create a duplicate of App.xaml. Right-click App.xaml in the solution explorer window in Visual Studio, and select Copy. Right-click the project node and select Paste. Rename the inserted file to AppDesigner.xaml, and delete AppDesigner.xaml.cs, since you don't need two instances of the code behind file. Next, right-click the project node and select Unload Project (agree to save changes if prompted). Right-click the same project node and select Edit DesignTimeDataSample.csproj. Replace the following XAML:

<ApplicationDefinition Include="App.xaml">
  <SubType>Designer</SubType>
  <Generator>MSBuild:Compile</Generator>
</ApplicationDefinition>
<ApplicationDefinition Include="AppDesigner.xaml">
  <Generator>MSBuild:Compile</Generator>
  <SubType>Designer</SubType>
</ApplicationDefinition>

With this:

<ApplicationDefinition Include="AppDesigner.xaml" Condition="'$(DesignTime)'=='true' 
OR ('$(SolutionPath)'!='' AND Exists('$(SolutionPath)') 
AND '$(BuildingInsideVisualStudio)'!='true' AND '$(BuildingInsideExpressionBlend)'!='true')">
  <SubType>Designer</SubType>
  <Generator>MSBuild:Compile</Generator>
</ApplicationDefinition>
<ApplicationDefinition Include="App.xaml" Condition="!('$(DesignTime)'=='true' 
OR ('$(SolutionPath)'!='' AND Exists('$(SolutionPath)') AND '$(BuildingInsideVisualStudio)'!='true' 
AND '$(BuildingInsideExpressionBlend)'!='true'))">
  <SubType>Designer</SubType>
  <Generator>MSBuild:Compile</Generator>
</ApplicationDefinition>

This is essentially telling MSBuild to only compile the AppDesigner.xaml file when in DesignTime, and to only compile App.xaml when not in DesignTime. Right-click the project node again and select Reload Project (remembering to save any changes). Your application should build and run in Visual Studio without exception and your design team will thank you, because the design time data is still available in Expression Blend (note: you may need to force a rebuild in Expression Blend and/or reopen any pages that use the design time data).

That's how to effectively disable the design time data in your Windows Phone application at runtime, without sacrificing the designer experience in Expression Blend. There are other alternatives to the MSBuild option described here, but they tend to sacrifice part or all of the design time experience in Expression Blend. It's important to preserve this experience to facilitate changes to the design of the application throughout your application's lifecycle.

 

 

About the Author

Nick Randolph runs Built to Roam, a consulting company that specializes in training, mentoring and assisting other companies build mobile applications. With a heritage in rich client applications for both the desktop and a variety of mobile platforms, Nick currently presents, writes and educates on the Windows Phone platform.

comments powered by Disqus

Featured

Subscribe on YouTube