Debugging Design-Time Exceptions

It’s not entirely uncommon for projects that run fine to not work when loaded into Blend for editing:

image001

There are a variety of issues that can cause this- some are bugs that we’re working to address, others are things that need to be fixed by the application developer. Unfortunately designability doesn’t always come free.

The exception information that’s displayed often has some useful information, but for complex projects I can save some guessing by just debugging through it using VS. This post will describe some steps to help you out.

Steps to Debug Exceptions on the Design Surface in Blend

  1. Open the project with the error in Blend, but close the XAML file which contains the error.
     
  2. Open the same project in Visual Studio.
     
  3. Attach the VS debugger to the Blend process:
    1. In Visual Studio, go to Debug->Attach to Process.
       
    1. Select Blend.exe from the Available Processes list:

 image003

    1. Ensure that the “Attach To:” field reads ‘Managed Code’, if not, click Select… and change it to “Managed Code”

attachManageCode

    1. Click Attach
       
  1. Set Visual Studio to break on all exceptions:

    1. In Visual Studio, go to Debug->Exceptions…
       
    2. Ensure there’s a checkbox beside Common Language Runtime Exceptions:

 image008

    1. Click “OK” 
       
  1. Go back to Blend, and open up the XAML file containing the error.

  2. What ideally will happen is that you’ll get a nice stack trace leading to some of your code in Visual Studio and the cause is readily apparent:

image009

Common Examples of Errors We See
Let’s look at some common errors we often encounter with Silverlight 2 projects:

Common Error Accessing the web page while in the design surface, such as the above example. Anything related to HtmlPage is off-limits when in design time since the app is not being hosted in a web page:

if (HtmlPage.IsEnabled) {
    HtmlPage.Window.Alert("Hello World!");
}

Common Error
Accessing isolated storage in the design surface, or even accessing a method which contains a call to isolated storage. When hosted at design-time the Silverlight application is actually running on the desktop .NET runtime where these APIs do not exist. This means that methods which contain a call to isolated storage cannot be called even if the isolated storage is never accessed.

Bad:

public Page() {
    InitializeComponent();

    if (HtmlPage.IsEnabled) {
        using (Stream s =
IsolatedStorageFile.GetUserStoreForApplication()
.CreateFile("testdata")) {
        }
}

Good:

public Page() {
        InitializeComponent();

    if (HtmlPage.IsEnabled)
        this.InitializeData();
}

public void InitializeData() {
       using (Stream s = IsolatedStorageFile.GetUserStoreForApplication()
.CreateFile("testdata")) {
       }
}

Bonus Trick
One of the other complaints that I’ve heard frequently is that debugging templates errors in Silverlight 2 Beta 2 is not so easy. Too often you just get a stack trace with a bunch of nonsense calls to Measure or MeasureOverride. To help debug these errors in my own projects I’ve started overriding MeasureOverride in my own controls so that they’ll appear in the stack trace as well. This way when a template fails to load, I can quickly tell where it was in the application.

protected override Size MeasureOverride(Size availableSize) {
     return base.MeasureOverride(availableSize);
}

Hope this helps!

- Pete Blois