The XAML designer in Blend & VS is a projection of a running application (see Mysteries of XDesProc–Revealed!), but unlike a full-fledged app, usage of certain programming constructs and resources might cause the designer to crash or behave in an unexpected manner.
Note: This post and the examples shown are written in the context of the XAML Metro style app designer, but some of them apply to Windows Presentation Foundation (WPF), Silverlight, and Windows Phone designers as well.
First, a quick overview of what code runs in the designer and what doesn’t.
- The code-behind of the instances of user controls and custom controls in the active XAML page are run in the designer.
- WINRT or CLR types that you declare in XAML as resources are instantiated in the designer process.
- Events dependent on CoreWindow and Input events will not be fired in the designer.
Keeping the above statements in mind, let’s review some things that might cause the designer to crash or behave unexpectedly.
As the designer process is basically a WPF Application that hosts XAML runtime components, types like CoreWindow and CoreDispatcher are unavailable. CoreDispatcher is generally used to marshal an operation from a non-UI thread to the UI thread or schedule it for later execution on the UI thread. Since there is no CoreWindow in the designer process, CoreDispatcher objects in the designer will always evaluate to NULL. Hence, any user controls and custom controls that use this construct in their code-behind might not work correctly in the designer.
When we detect that an instance of a user control or custom type cannot be created, we catch all resulting exceptions and wrap them in an error report linked to that specific instance, and continue creating the rest of the document.
If you drill down into the exception details, you will get an error report similar to the image below.
The above exception makes it clear that in this example, the display problem is due to a Dispatcher invocation in the constructor of the control.
The question now is, “How do I safeguard my control from dropping dead in the designer?” Well, there is a pretty nifty way of working around this. The code sample below illustrates the approach.
The key is Windows.ApplicationModel.DesignMode.DesignModeEnabled. This property always evaluates to true in the designer and to false during runtime. For a seamless design experience, the recommended approach is to wrap troublesome invocations with this construct. (For WPF and Silverlight design mode detection, check out Laurent Bugnion’s great blog post Detecting design time mode in WPF and Silverlight.)
This particular issue is not only unique to the CoreDispatcher but is also applicable to properties like CoreWindow.Current.
File I/O in the Designer
Files packaged as a part of the app will not be available for the code running inside the designer process. Two notable exceptions to this rule are Images and XAML files.
To be more specific, file access in the project that does not go through XAML APIs will not be available in the designer. The reason for this constraint is that the structure of the App when deployed for the designer process varies radically from the structure of an installed Windows 8 App.
Design time resolution of XAML files and Images are enabled by a callback mechanism from the platform to the designer process. Whenever the XAML platform encounters a resource that it cannot resolve, it calls the designer process, which supplies it with the correct location of the resource. Other file types referenced either by relative or ms-appx URI will not be available at the expected location in the designer process.
Let’s say you are trying to access an .xml file that is a part of your project in a User Control in the designer process. You might run into the below exception:
The code below, which was called from the constructor of the User Control, threw the above exception.
A couple of workarounds
Here are two possible workarounds.
- Wrap the call to the File IO using the Windows.ApplicationModel.DesignMode.DesignModeEnabled flag to prevent this exception from happening.
- If you are using this file for design time data, an alternative option is to use XAML files. (Blend 4 Sample data)
As always, we welcome your comments and feedback.
Harikrishna Menon, Program Manager – Blend for Visual Studio