Blend for Visual Studio 2012 Platform Errors

With the recent release of Visual Studio 2012 Update 2 there is finally a real release version of Blend that can support WPF projects on .NET 4.5 in the form of Blend for Visual Studio 2012 (installed with the VS update package). Unfortunately there is a nasty and obscure error that can come up unexpectedly in applications that work fine in Visual Studio and at runtime.

The issue manifests as the dreaded Invalid Markup screen:

clip_image001

and a series of errors in XAML of the form “X is not supported in a Windows Presentation Foundation (WPF) project.” for every element in your project’s XAML:

List of Blend design surface errors from incorrectly unsupported elements.

The cause of the issue is a problem with how Blend loads solution configurations. Continue reading

Initial Thoughts on Blend 3 MIX Preview

After trying out the new features in Blend 3 I’m definitely looking forward to the full release. It already seems to be more responsive than Blend 2 SP1 while navigating around files, templates, selected elements, etc, even at this pre-Beta stage. I was disappointed to see SketchFlow missing from the Preview, but look forward to it being included when it’s stable enough.

There are a bunch of nice UI tweaks:

  • Tool Panels now allow pinning (like in VS) to autohide. Data and Objects and Timeline are also now their own panels so they can move around freely. The left side tool strip now floats and docks too.
  • The Active Container is no longer a static setting. It’s still possible to set it to a fixed object, but now it must be done from the right click menu (Pin Active Container) instead of double clicking. I was annoyed by this at first and wondering why there was no yellow selection border, but then realized that Blend was inferring a container based on what I was doing. Double clicking to add an element now uses the current selection as the container to add to, or its parent if it doesn’t support children. A blue border takes the place of the yellow indicator in these cases.

Even better, when adding by dragging directly on the design surface, the container is inferred graphically and switches (with blue border) as you move the cursor around.

  • Like the active container setting, elements are similarly highlighted with a blue border as you mouse around with the selection arrow tool, making it easy to find elements. This includes elements that are buried in layers of panels, and selecting an element is as easy as clicking on it when it’s highlighted, virtually eliminating the need for using the right click “Set Current Selection” menu item (although it is still available). I haven’t had to use it yet once.
  • Design-time sizing is available on more root container than before, including both Control and Data Templates. Rather than being set on the template itself the size is set on the first element in the tree.

  • The old Gradient tool that was pretty much only useful for rotating gradients now allows direct setting of stops on the design surface. Each one is shown as a circle and can be dragged to a different spot or edited in place (with popup color picker) by double clicking. Alt-clicking adds new stops and dragging a stop out of the gradient area removes it. The Properties panel brush editor itself has also added the ability to set a gradient stop position as a numeric percentage (great for translating from Illustrator) and reverse the order of gradient stops.

  • Annotations allow for design notes to be added directly to the UI that only show up in Blend (think comments for designers). I tried adding some in a real WPF project and the attached properties they created didn’t seem to have any effect on VS or Blend 2. I haven’t figured out where the AnnotationManager class lives so I’m hesitant to leave notes on files that other people need to edit without Blend 3 but at least they didn’t cause any immediate backward compatibility issues on my own box.
  • New keyboard shortcuts abound. Look around the menus to find them – the help hasn’t been updated yet.

My favorite part of the new version is design time data – something I’ve been doing awkward workarounds for since I started using Blend. There are lots of options, but my favorite so far is the generated sample data source. I first tried importing an XML file, which gave me a full set of data and showed all the available fields, including nested collections. I then set up another data source from scratch, using only the Blend UI to define the data structure:

Anywhere there’s a “+” a simple, complex or collection property can be added. Simple properties can be set as String, Number, Image, or Boolean types, with further options for each. String properties can be set to things like Names, Dates or Phone numbers to provide realistic looking data. Images of chairs are provided out of the box but can be replaced by pointing to a folder of image files of your choice.

All of this results in a generated class that includes a bunch of dummy data and is declared as a resource in location of your choice. Any element from the data source can then be dragged onto the design surface to set up a binding or generate a bound control. I haven’t quite gotten the hang of predictably hooking up data by dragging but through a combination of dragging elements and using Blend’s data binding window (which consistently displayed my test data structure through the Data Context tab) I managed to quickly set up a complete multi-level master detail UI for the structure I set up without jumping into XAML at all. An option allows you to switch between using the data only at design time (d:DataContext) or at design and run-time (DataContext) – this should be good for initial testing of a UI.

Through a few hours of working on a live WPF project I haven’t had any problems using the new version and hopping back and forth to VS. I even tried opening in Blend 2, 3, and VS and making changed in all 3 with no problems. I haven’t done much more than start up a new Silverlight 3 project but that worked fine too and the Preview install doesn’t appear to have negatively impacted my existing Silverlight 2 dev environment.

Get the preview here

and if you’re using TFS look at http://code.msdn.microsoft.com/KB967483 for the hotfix needed to hook up the Preview’s source control integration.

Setting Up Test Data for Blend

One of the big challenges in using Blend to set up an application that relies heavily on dynamic data is that without realistic data available at design-time, what you see isn’t what you get at run-time. Blend includes some basic built in data generation that can be useful for simple data structures but this won’t really help much if you have conditional layout that is expecting specific values.

If all you need is a generic set of data to fill out an ItemsControl you can use Blend to generate design-time data for itself. Select the control to generate data for and open the data binding dialog for the ItemsSource property (either directly or through the “Bind ItemsSource to Data…” context menu option). Locate the collection to bind to and click the “Define Data Template” button at the bottom. This dialog can set up a basic data template (that will probably need some tweaking later) and more importantly includes the “Generate sample data” checkbox at the bottom. Selecting this adds a new d:UseSampleData=”True” setting on the ItemsControl (along with the d and mc xmlns’s used by Blend) which signals Blend to create data for the types of the items in the bound collection. Unfortunately, the values generated are pretty limited. Strings are fruits, ints are small values, and enums are chosen at random (in the latest 2.0 SP1 version; earlier versions didn’t do enums).

When the built in generation isn’t enough test data can be made available in a number of ways but there are some challenges to getting it to show up. In most cases the key to getting Blend specific data relies in some way on a check of the DesignerProperties.IsInDesignMode Attached Property. This value is false at run-time and true at design-time in Blend. It can be checked with a call to DesignerProperties.GetIsInDesignMode, passing a DependencyObject instance or statically with the more verbose (bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(DependencyObject)).Metadata.DefaultValue.

Since Blend skips the constructor and many initialization event handlers declared in the code-behind of the view being loaded, anything that is hooked up in those methods will not be called in Blend. This can make it tricky to even get to code that can check IsInDesignMode and generate your data. To ensure code gets called it needs to somehow be referenced from XAML. A few ways to do this:

  • A property assignment of a new object with generation code in the constructor

<Window.DataContext>
    <local:ViewModel />
</Window.DataContext>

  • A Binding to a property that includes generation code

DataContext=”{Binding RelativeSource={RelativeSource Self}, Path=ViewModel}”

  • An assignment to a custom attached property that includes generation code in its set method

For any of these methods you should either use an IsInDesignMode check or make sure that everything being run will work at both Blend design-time and run-time. See my post on debugging Blend errors for more on Blend unsafe code. The simplest way to actually get the test data from your code to Blend is by assigning it to a DataContext property of some element (as in the examples above). If you plan ahead you should be able to get both your run-time and design-time data through the same DataContext properties which will keep your Binding behaviors consistent.

Debugging Blend Errors

Blend has been getting more stable with frequent releases including SP1, Blend 2 etc but it still can’t render everything, even from an application that runs flawlessly at runtime. There are lots of things that can break the Blend renderer but tracking down exactly what broke your window/page/control can be difficult and time consuming. In some cases the location can be found by taking advantage of how Blend hosts applications. When Blend renders XAML it’s running the code just like at runtime and the code can be debugged in the same way. In cases where non-XAML Exceptions are breaking the renderer Visual Studio can attach to Blend itself and break to the exact location that’s causing the problem.

The primary reason errors occur in Blend that don’t show up at runtime is that Blend acts as a host for the application. This causes things that are evaluated relative to the running application like config files and certain types of relative resource references to look in the wrong place. The pack:application syntax in particular causes invalid references. The ResourceDictionary hierarchy is also different when running in Blend. In versions prior to Blend 2 Feb Beta App.xaml resources aren’t automatically resolved using StaticResource the way they are at compile time. Even the newest versions run into problems resolving references inside things like UserControls when rendered as part of a Window. XAML errors generally show up in the Blend errors window and can be linked to a specific line (with varying accuracy depending on the version) while errors deeper in code need Visual Studio debugging.

Blend XAML Error

To debug an application inside Blend open the project in both Visual Studio and Blend at the same time. Before opening the broken component in Blend attach Visual Studio to the process with Debug->Attach To Process and select Blend.exe from the list. To make sure the Exception isn’t just swallowed by Blend set Visual Studio to break on all CLR Exceptions by selecting Thrown in the Debug->Exceptions for Common Language Runtime Exceptions.

Exception Options

Once you’ve tracked down an Exception in code you have a few choices. You can fix the error if it’s something that you determine shouldn’t be happening. If it’s due solely to the peculiarities of Blend and you want to leave the code as is, except when running in Blend, WPF provides a way to check whether Blend (or some other designer) is hosting the code. DesignerProperties.IsInDesignMode is set to True by Blend and can be accessed from anywhere in a WPF application with

(bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof(DependencyObject)).Metadata.DefaultValue

Any code that breaks Blend can just be executed conditionally when this value is false.

One of the key advantages of using WPF is the promise of direct collaboration between designer and developer. Fixing Blend rendering errors will enable design and development of your application simultaneously without worrying about keeping application code and static designs from separate teams in sync.

Triggers and States in Blend

After using the Expression Interactive Designer CTPs and getting used to that UI, I’m now trying to learn the completely different Blend UI. After some confusion with timelines and the new UI I finally got a state based property change working in a template in Blend.

   

The goal is to produce XAML like this from Blend:

   

<CONTROLTEMPLATE.TRIGGERS>

<TRIGGER Value=”True” Property=”IsChecked”>

<SETTER Value=”Blackadder ITC” Property=”FontFamily” />
<SETTER Value=”24″ Property=”FontSize” />

</TRIGGER>

</CONTROLTEMPLATE.TRIGGERS>

   

This should cause the template checkbox to switch to a large script font when it is checked and back to default when unchecked.

The obvious thing that the UI initially seems to push you towards is creating an animation timeline to do this. After entering template editing mode the Triggers window looks like this:

Trigger1

 

The +Property button then allows you to add a new Property based Trigger, which is what we’re looking for. After adding the new Trigger and picking from the property dropdown we get to:

Trigger2

At this point the obvious thing to do seems to be adding to the next step in the window, “Actions when activating”, but this will actually create the timeline we’re trying to avoid. What isn’t obvious is that you’re actually done with the Property-State Trigger and since recording is on any property changes you make now will be attached to the Trigger as Setters, just like we want. Over in the Properties->Text panel I change my font and then exit template editing mode. That’s it. Now when we click the checkbox we go from CheckMe1 to CheckMe2.

Another Blend oddity after coming from EID – there’s no more code-behind editor (which is okay because the EID one wasn’t even close to VS) so you can’t directly jump to event handlers. There is now integration with Visual Studio though so you can create event handlers in code from the Properties tool window just like a WinForm in VS and it will create and open the code into Visual Studio if you have it installed.

Events