The team blog of the Expression Blend and Design products.
It’s not entirely uncommon for projects that run fine to not work when loaded into Blend for editing:
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
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 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")) { } }
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
It’s not entirely uncommon for projects that run fine to not work when loaded into Blend for editing
Great post!
Writing code designers can work with is something I'm really interested in...
What's the best way to detect if an object is being consumed inside Blend? Currently I do a if(HtmlPage.IsEnabled) { Populate Some Dummy Design Time Data } - That way the designer who is consuming a bindable object gets a better experience.
Do you have any other tips/tricks onw how to make the Blend 2.5 experience more pleasent when working with "real code"?
I don't see the difference between your good and bad example. All you did is move the code into another method. What am I missing?
The difference between the good code and the bad code in this case is that the method containing the code cannot be called, if it does then the CLR will attempt to Just-In-Time compile (JIT) the code and run into the missing method exception.
The resolution is to move the code out of the constructor and into another method with a guard around it to prevent it from getting compiled.
It may not be the most obvious thing to do but if your getting design time errors in Blend – attach Visual
This article was really helpful. I was getting a "Cannot create an instance of X" error in Microsoft Expressions Blend, despite the Solution loading properly in Visual Studio. I'm still debugging, but it looks like the problem was caused by the HtmlPage issue you mentioned above.
Great article Pete :) it has been helpfull
Thanks. Really useful. You might also have to disable 'My code' debugging option in Visual Studio -> Tools -> Options for this to work.