Extending Blend for Visual Studio
Once upon a time, in a galaxy far away, I wrote a couple of tutorials on how to write extensions for Expression Blend. Today there’s still not much information available on how to write your own extensions. But it is still possible to extend Blend for Visual Studio. The way to do this is slightly changed though.
I recently came across a question at StackOverflow.com that made me decide to update/rewrite some that older tutorials.
Instead of building some dummy extension I’d like to show you how to build an extensions that might be useful for developers of Windows Store apps and Windows Phone apps. The extension is going to display a list of characters of the Segoe UI Symbols font you can use in you apps.
Getting Started
To be able to build directly into the extensions folder of Blend and have Visual Studio debug them you’ll have to start Visual Studio as administrator.
When Visual Studio is started create a new WPF User Control Library project. This will add the necessary references for creating a user control that will be our panel in Blend.
I named the extension SegoeSymbol, but feel free to use anything you like…
Next we’ll have to change some of the configurations of the project to have Blend pick the extension right from it’s extensions folder.
Go to the properties of the the project and change the Assembly Name on the Application tab to “SegoeSymbol.Extension” . This will name the assembly SegoeSymbol.Extension.dll. All extensions need to have the .extension.dll suffix.
Also change the Target framework to .NET Framework 4.5.
Set the Output Path on the Build tab to “c:\Program Files (x86)\Microsoft Visual Studio 11.0\Blend\Extensions\” . If you have installed Visual Studio 2012 in any other location this path might be different. Also, make sure the Extensions folder exists.
The last property to changes is the Start Action on the Debug tab. Set this to the full path to “Blend.exe”. This way Visuals Studio will start Blend when you hit F5 and attaches the debugger to the process enabling you to set breakpoints and such.
Code
Before we can do anything with this extension we need some code. The project we just created doesn’t have a class file yet, so we’ll have to add a one. Name it SegoeSymbol. This class will be the entry point for the extension.
This class has to implement the IPackage interface from Blend. To get this interface you’ll have to reference Microsoft.Expression.Extensibility.dll. You can this assembly in the root folder of Blend, the same folder you’ve found Blend.exe in a bit earlier.
Implementing this interface will give you two methods, Load and Unload. The Load method is called when Blend loads the extension. And, you might have guessed, Unload is called when Blend unloads the extension. Blend will load the the extension when it is started and unload the extension when it is shut down.
Blend for Visual Studio uses the Managed Extensibility Framework, or MEF, to load extensions. MEF is included in the .NET framework. All you have to do is find the reference to System.ComponentModel.Composition. MEF works by decorating a class you want to enable as extensions with the Export attribute and providing that with the type you’d like to export. The other side, Blend in this case, is using an Import based on the IPackage interface to get to the extension. By now your code should look something like this:
namespace SegoeSymbol
{
using System.ComponentModel.Composition;
using Microsoft.Expression.Extensibility;
[Export(typeof (IPackage))]
public class SegoeSymbol : IPackage
{
public void Load(IServices services)
{
}
public void Unload()
{
}
}
}
One last thing before you build and run your code. By default all assemblies referenced that are not in the GAC are copied to the output directory. Because Blend has everything you need, you can set the Copy Local property of all references to False. If you need to have a reference included with your extensions you can leave that one to true.
If you like you can try it out now… If you place breakpoints at the opening brackets of both methods you will see them both hit when opening and closing Blend.
A small thing you might run into when developing extensions is that Blend will lock the extension assemblies when it has them in use. This means you can’t have Visual Studio compile and build you extensions when Blend is running. Even to the point where if you close Blend a process, Microsoft Visual Studio XAML UI Designer (32 bit), will keep the files locked. I have to look a bit more into why and when this process is used. But you often have to go into the process explorer and end the task by hand. If you hit the “stop” button in Visual Studio it will kill Blend most of the time, which unlocks the files. I don’t know if this is a bug or a feature.
I’ll get back to this class in a second. First we should have a look at the…
User Interface
An extension needs a user interface, right? The user interface doesn’t do anything with Blend itself or with the extension so I’ll go over it rather quickly.
Because we started with the WPF User Control Library template we already have one. I renamed this to CharacterSelector.
Lets have a look at the XAML part of the UI. It’s basically just a ListBox with some styling. I changed the ItemsPanelTemplate (on line 27) to contain a WrapPanel instead of a StackPanel so all icons will be placed next to each other until a row is full at which point it will wrap to the next row.
The ItemTemplate, defined on line 14, draw a border around a TextBlock that contains the character in the Segoe UI Symbol font.
The whole thing is combined in a ListBox, line 34. The selection changed event is handled in the code behind.
<UserControl x:Class="SegoeSymbol.CharacterSelector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="322.667"
Width="Auto"
Height="Auto"
MinWidth="325">
<UserControl.Resources>
<ResourceDictionary>
<DataTemplate x:Key="ItemTemplate">
<Border BorderThickness="1"
Width="50"
Height="50"
BorderBrush="White">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock Text="{Binding Character}"
FontFamily="Segoe UI Symbol"
FontSize="24" />
</Grid>
</Border>
</DataTemplate>
<ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
<WrapPanel />
</ItemsPanelTemplate>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<ListBox x:Name="listBox"
Background="{x:Null}"
ItemTemplate="{DynamicResource ItemTemplate}"
ItemsPanel="{DynamicResource ItemsPanelTemplate1}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SelectionChanged="listBox_SelectionChanged" />
</Grid>
</UserControl>
In the code behind I fill the selection with characters and handle the selection. The list of characters is created with a simple for loop at line 16. This loop instantiates a helper class MetroIcon (see line 57) and fills it with a number and the corresponding character. After the loop the collection of characters is assigned to the ItemsSource of the ListBox (line 27).
When an element of the ListBox is selected, when the extension is running in Blend, the Listbox_SelectionChanged event handler is called (line 27). To keep things simple, the character selected is copied to the Windows clipboard. As text, but formatted in a way xaml-text can handle it.
Here’s the code:
namespace SegoeSymbol
{
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
/// <summary>
/// Interaction logic for CharacterSelector.xaml
/// </summary>
public partial class CharacterSelector : UserControl
{
public List<MetroIcon> Collection = new List<MetroIcon>();
public CharacterSelector()
{
Collection = new List<MetroIcon>();
for (int i = 0xE100; i < 0xE271; i++)
{
Collection.Add(new MetroIcon()
{
Character = ((char)(i)).ToString(),
Value = i
});
}
InitializeComponent();
listBox.ItemsSource = Collection;
}
/// <summary>
/// Handles the SelectionChanged event of the listBox control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="SelectionChangedEventArgs"/> instance
/// containing the event data.
/// </param>
private void listBox_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
if (e.AddedItems != null && e.AddedItems.Count>0)
{
var metroIcon = e.AddedItems[0] as MetroIcon;
if (metroIcon != null)
{
string val = string.Format("&#x{0:X};", metroIcon.Value);
Clipboard.SetData(DataFormats.Text,val);
}
listBox.SelectedItem = null;
}
}
}
/// <summary>
/// Data class for holding Character and value
/// </summary>
public class MetroIcon
{
public string Character { get; set; }
public int Value { get; set; }
}
}
Lets have a look at gluing the whole thing together.
Adding the control to Blend
We’re going to make some magic happen in the Load method created earlier in this tutorial. Blend calls the load method and passes it its IServices implementation. You can use this class to get access to various services that Blend exposes. One useful service is the IWindowService. This service is responsible for the panels you see all around Blend. To be able to use the IWindowService interface you need reference Microsoft.Expression.Framework.dll and make sure you set “Copy Local” on false.
To get access to IWindowService you need to call the GetService method on services that was passed as a parameter. When you give this generic method the type IWindowService, it will return an instance of that type that Blend is using.
Next, create an instance of the CharacterSelector control we created in the previous chapter. If you someday need IServices in a user control, just extend the constructor and pass it in.
The last thing to do is register the control as a “Palette”. Palettes are the panels in Blend. To register a new palette call the RegisterPalette method on windowService and give it an identifier, the instance of the control and a title. You can provide a fourth, optional, parameter to set some extended properties on the palette, but we’ll use the defaults for now.
The Load methods should be looking something like this by now:
public void Load(IServices services)
{
IWindowService windowService = services.GetService<IWindowService>();
CharacterSelector characterSelector = new CharacterSelector();
windowService.RegisterPalette("SegoeSymbolExtionsion",
characterSelector,
"SegoeSymbol");
}
At this point you should be able to hit F5 and find the extension in Blend.
After Blend is started you need to create or open a project. If you look in the Window menu, the palette is shown right there.
When the SegoeSymbol panel is visible it behaves like all other panels in Blend. In this case it is docked next to the Resources panel.
What’s next?
I think we’ve got the basics down at this point. There are a lot more things you can do, like creating menus and commands or using documents and dialogs.
Please note that anything you just read is based on my own findings. There is no documentation available on writing these extension, no support and no guarantee it will even work in a next version of Blend for Visual Studio.
NuGet
If you often use open source libraries you probably have a large library with various tools, like I do. NuGet is an extension for visual studio that enables you to install, uninstall and upgrade open source packages into your application very easily. Say for example you want to use MvvmLight or Ninject in your project, with NuGet it’s nothing more that tell it to add the package to your project.
NuGet
NuGet (formerly known as NuPack) is a free, open source developer focused package management system for the .NET platform.
You can download the .vsix extension at http://nuget.codeplex.com.
After installing it you can start adding packages to your project in two ways. The first is by right clicking in the Solution Explorer and selecting the Add Library Package Reference… option.
This will present you with a dialog where you can find and install a package. To see the package available, select the Online option from the list on the left. You can use the text box on the top right to filter the list to get to the package you want to use. Hit the install button to add the package to your project.
To remove a package, go to the same window. The installed packages are shown on the first page. Hit the uninstall button next to the package you would like to remove from your project.
Another way of managing packages is thru a powershell like interface, using the keyboard. You can get to the console window by going to the View menu and selecting Other Windows –> Package Manager Console.
The following window will show up (the coloration might be different based on your personal color scheme settings in Visual Studio).
You can manage your packages by using a few simple commands.
-
- List-Package
- Install-Package
- Update-Package
- Uninstall-Package
These do exactly what can be expected. The Install, Update and Uninstall need at least the name of the package as parameter. You can type help before each of these commands to get information on the other parameters.
One last thing. You can use the Tab key to auto-complete commands and even parameters.
Gradient Importer for Expression Blend
Intro
Adobe Photoshop offers people the possibility to share gradients through .GRD files. These files can be found very easily on various sites. This extension for Expression Blend allows you to import these files and use them in your Silverlight or WPF projects.
The extension makes use of some changes to Expression Blend made in SP1. You must have Blend SP1 installed to use this extension.
Know limitations
The extension isn’t finished yet. I haven’t worked out all the bugs yet, but this first release should enable you to import most of the .GRD files.
In Adobe Photoshop it is possible to create a noise gradient type. This type of gradient isn’t available in Xaml. At this point the extension will show an error when a file containing a noise gradient is opened. In a future version the noise gradient will be skipped.
Because there is no documentation on how to interact with Expression Blend from extensions I have not been able to create a new resource entry from code. I’m not even sure if this is possible at all. Therefore I have chosen to show the Xaml created from the imported gradient and give you the opportunity to copy the Xaml to the clipboard. This way you can place it wherever you want.
I have tested the extension with various .GRD files, but it is possible you may encounter files that do not import and generate errors. Please take the time to inform me about these and send me an email with the .GRD file or a link to it.
Installation
You can download the extension here. All you have to do is extract the file in a temporary directory and copy the .DLL into the extensions folder of Expression Blend 4. If you have the FXG importer installed that came with SP1 this folder should already be there. If not, just add it to Expression Blend folder and Blend knows what to do with it.
Using the extension
After the .DLL file of the extension is placed in the /extensions folder you should restart Expression Blend. Open the solution you want to add the imported gradient to.
Go to the File menu and choose the newly added menu item “Import gradient file…” .
An dialog window should pop up. Click on the “Load .GRD” button in to top right corner. The should bring up a file dialog. Browse to the .GRD file, select it and click “Open”.
The file is opened and its contents are shown in the list box. Select the gradient you would like to add to your project and click “Import”.
A new dialog window containing the Xaml for this gradient. You can alter the Xaml if needed.
Click on the “Copy to Clipboard” button to copy the Xaml to the clipboard.
After this you can close the window and paste the Xaml into the resource location of your choice.
What to expect next
I have planned to work on blog post about the inner workings of this extension. Mainly focused on how it works inside Expression Blend. If you run into any issues, have comments or if you have feature requests, please let me know by adding a comment to this post or by sending me an email.
Building a “real” extension for Expression Blend
Last time I showed you how to get started building extensions for Expression Blend. Lets build a useful extension this time and go a bit deeper into Blend.
- Source of project => here
- Compiled dll => here (extract into /extensions folder of Expression Blend)
The Extension
When working on large Xaml files in Blend it’s often hard to find a specific control in the "Objects and Timeline Pane”. An extension that searches the active document and presents all elements that satisfy the query would be helpful. When the user starts typing a search query a search will be performed and the results are shown in the list. After the user selects an item in the results list, the control in the "Objects and Timeline Pane” will be selected. Below is a sketch of what it is going to look like.

The Solution
Create a new WPF User Control project as shown in the earlier tutorial in the Configuring the extension project section, but name it AdvancedSearch this time. Delete the default UserControl1.Xaml to clear the solution (a new user control will be added later thought, but adding a user control is easier then renaming one).
Create the main entry point of the addin by adding a new class to the solution and naming this AdvancedSearchPackage. Add a reference to Microsoft.Expression.Extensibility and to System.ComponentModel.Composition . Implement the IPackage interface and add the Export attribute from the MEF to the definition. While you’re at it. Add references to Microsoft.Expression.DesignSurface, Microsoft.Expression.FrameWork and Microsoft.Expression.Markup. These will be used later.
The Load method from the IPackage interface is going to create a ViewModel to bind to from the UI. Add another class to the solution and name this AdvancedSearchViewModel. This class needs to implement the INotifyPropertyChanged interface to enable notifications to the view. Add a constructor to the class that takes an IServices interface as a parameter.
Create a new instance of the AdvancedSearchViewModel in the load method in the AdvanceSearchPackage class. The AdvancedSearchPackage class should looks like this now:
using System.ComponentModel.Composition;
using Microsoft.Expression.Extensibility;
namespace AdvancedSearch
{
[Export(typeof(IPackage))]
public class AdvancedSearchPackage:IPackage
{
public void Load(IServices services)
{
new AdvancedSearchViewModel(services);
}
public void Unload()
{
}
}
}
Add a new UserControl to the project and name this AdvancedSearchView. The View will be created by the ViewModel, which will pass itself to the constructor of the view. Change the constructor of the View to take a AdvancedSearchViewModel object as a parameter. Add a private field to store the ViewModel and set this field in the constructor. Point the DataContext of the view to the ViewModel. The View will look something like this now:
namespace AdvancedSearch
{
public partial class AdvancedSearchView:UserControl
{
private readonly AdvancedSearchViewModel _advancedSearchViewModel;
public AdvancedSearchView(AdvancedSearchViewModel advancedSearchViewModel)
{
_advancedSearchViewModel = advancedSearchViewModel;
InitializeComponent();
this.DataContext = _advancedSearchViewModel;
}
}
}
The View is going to be created in the constructor of the ViewModel and stored in a read only property.
public FrameworkElement View
{
get; private set;
}
public AdvancedSearchViewModel(IServices services)
{
_services = services;
View = new AdvancedSearchView(this);
}
The last thing the solution needs before we’ll wire things up is a new class, PossibleNode. This class will be used later to store the search results. The solution should look like this now:

Adding UI to the UI
The extension should build and run now, although nothing is showing up in Blend yet. To enable the user to perform a search query add a TextBox and a ListBox to the AdvancedSearchView.xaml file. I’ve set the rows of the grid too to make them look a little better. Add the TextChanged event to the TextBox and the SelectionChanged event to the ListBox, we’ll need those later on.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox TextChanged="SearchQueryTextChanged"
HorizontalAlignment="Stretch"
Margin="4"
Name="SearchQuery"
VerticalAlignment="Stretch" />
<ListBox SelectionChanged="SearchResultSelectionChanged"
HorizontalAlignment="Stretch"
Margin="4"
Name="SearchResult"
VerticalAlignment="Stretch"
Grid.Row="1" />
</Grid>
This will create a user interface like:

To make the View show up in Blend it has to be registered with the WindowService. The GetService<T> method is used to get services from Blend, which are your entry points into Blend.When writing extensions you will encounter this method very often. In this case we’re asking for an IWindowService interface. The IWindowService interface serves events for changing windows and themes, is used for adding or removing resources and is used for registering and unregistering Palettes. All panes in Blend are palettes and are registered thru the RegisterPalette method.
The first parameter passed to this method is a string containing a unique ID for the palette. This ID can be used to get access to the palette later.
The second parameter is the View.
The third parameter is a title for the pane. This title is shown when the pane is visible. It is also shown in the window menu of Blend.
The last parameter is a KeyBinding. I have chosen Ctrl+Shift+F to call the Advanced Search pane. This value is also shown in the window menu of Blend.
services.GetService<IWindowService>().RegisterPalette(
"AdvancedSearch",
viewModel.View,
"Advanced Search",
new KeyBinding
{
Key = Key.F,
Modifiers = ModifierKeys.Control | ModifierKeys.Shift
}
);
You can compiler and run now. After Blend starts you can hit Ctrl+Shift+F or go the windows menu to call the advanced search extension.
Searching for controls
The search has to be cleared on every change of the active document. The DocumentServices fires an event every time a new document is opened, a document is closed or another document view is selected. Add the following line to the constructor of the ViewModel to handle the ActiveDocumentChanged event:
_services.GetService<IDocumentService>().ActiveDocumentChanged += ActiveDocumentChanged;
And implement the ActiveDocumentChanged method:
private void ActiveDocumentChanged(object sender, DocumentChangedEventArgs e)
{
}
To get to the contents of the document we first need to get access to the “Objects and Timeline” pane. This pane is registered in the PaletteRegistry in the same way as this extension has registered itself. The palettes are accessible thru an associative array. All you need to provide is the Identifier of the palette you want. The Id of the “Objects and Timeline” pane is “Designer_TimelinePane”. I’ve included a list of the other default panes at the bottom of this article. Each palette has a Content property which can be cast to the type of the pane.
var timelinePane = (TimelinePane)_services.GetService<IWindowService>()
.PaletteRegistry["Designer_TimelinePane"]
.Content;
Add a private field to the top of the AdvancedSearchViewModel class to store the active SceneViewModel. The SceneViewModel is needed to set the current selection and to get the little icons for the type of control.
private SceneViewModel _activeSceneViewModel;
When the active SceneViewModel changes, the ActiveSceneViewModel is stored in this field. The list of possible nodes is cleared and an PropertyChanged event is fired for this list to notify the UI to clear the list. This will make the eventhandler look like this:
private void ActiveDocumentChanged(object sender, DocumentChangedEventArgs e)
{
var timelinePane = (TimelinePane)_services.GetService<IWindowService>()
.PaletteRegistry["Designer_TimelinePane"].Content;
_activeSceneViewModel = timelinePane.ActiveSceneViewModel;
PossibleNodes = new List<PossibleNode>();
InvokePropertyChanged("PossibleNodes");
}
The PossibleNode class used to store information about the controls found by the search. It’s a dumb data class with only 3 properties, the name of the control, the SceneNode and a brush used for the little icon. The SceneNode is the base class for every possible object you can create in Blend, like Brushes, Controls, Annotations, ResourceDictionaries and VisualStates. The entire PossibleNode class looks like this:
using System.Windows.Media;
using Microsoft.Expression.DesignSurface.ViewModel;
namespace AdvancedSearch
{
public class PossibleNode
{
public string Name { get; set; }
public SceneNode SceneNode { get; set; }
public DrawingBrush IconBrush { get; set; }
}
}
Add these two methods to the AdvancedSearchViewModel class:
public void Search(string searchText) { }
public void SelectElement(PossibleNode node){ }
Both these methods are going to be called from the view. The Search method performs the search and updates the PossibleNodes list. The controls in the active document can be accessed thru TimeLineItemsManager class. This class contains a read only collection of TimeLineItems. By using a Linq query the possible nodes are selected and placed in the PossibleNodes list.
var timelineItemManager = new TimelineItemManager(_activeSceneViewModel);
PossibleNodes =
new List<PossibleNode>(
(from d in timelineItemManager.ItemList
where d.DisplayName.ToLowerInvariant().StartsWith( searchText.ToLowerInvariant())
select new PossibleNode()
{
IconBrush = d.IconBrush,
SceneNode = d.SceneNode,
Name = d.DisplayName
}).ToList()
);
InvokePropertyChanged(InternalConst.PossibleNodes);
The Select method is pretty straight forward. It contains two lines.The first to clear the selection. Otherwise the selected element would be added to the current selection. The second line selects the nodes. It is given a new array with the node to be selected.
_activeSceneViewModel.ClearSelections();
_activeSceneViewModel.SelectNodes(new[] { node.SceneNode });
The last thing that needs to be done is to wire the whole thing to the View. The two event handlers just call the Search and SelectElement methods on the ViewModel.
private void SearchQueryTextChanged(object sender, TextChangedEventArgs e)
{
_advancedSearchViewModel.Search(SearchQuery.Text);
}
private void SearchResultSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(e.AddedItems.Count>0)
{
_advancedSearchViewModel.SelectElement(e.AddedItems[0] as PossibleNode);
}
}
The Listbox has to be bound to the PossibleNodes list and a simple DataTemplate is added to show the selection. The IconWithOverlay control can be found in the Microsoft.Expression.DesignSurface.UserInterface.Timeline.UI namespace in the Microsoft.Expression.DesignSurface assembly. The ListBox should look something like:
<ListBox SelectionChanged="SearchResultSelectionChanged"
HorizontalAlignment="Stretch" Margin="4"
Name="SearchResult" VerticalAlignment="Stretch" Grid.Row="1"
ItemsSource="{Binding PossibleNodes}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<tlui:IconWithOverlay Margin="2,0,10,0"
Width="12" Height="12"
SourceBrush="{Binding Path=IconBrush, Mode=OneWay}"
/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Compile and run. Inside Blend the extension could look something like below.

What’s Next
When you’ve got the extension running. Try placing breakpoints in the code and see what else is in there. There’s a lot to explore and build extension on. I personally would love an extension to search for resources.
Last but not least, you can download the source of project here. If you have any questions let me know.
If you just want to use this extension, you can download the compiled dll here. Just extract the . zip into the /extensions folder of Expression Blend.
Notes
Target framework
I ran into some issues when using the .NET Framework 4 Client Profile as a target framework. I got some strange error saying certain obvious namespaces could not be found, Microsoft.Expression in my case. If you run into something like this, try setting the target framework to .NET Framework 4 instead of the client version.
Identifiers of default panes
| Identifier | Type | Title |
|---|---|---|
| Designer_TimelinePane | TimelinePane | Objects and Timeline |
| Designer_ToolPane | ToolPane | Tools |
| Designer_ProjectPane | ProjectPane | Projects |
| Designer_DataPane | DataPane | Data |
| Designer_ResourcePane | ResourcePane | Resources |
| Designer_PropertyInspector | PropertyInspector | Properties |
| Designer_TriggersPane | TriggersPane | Triggers |
| Interaction_Skin | SkinView | States |
| Designer_AssetPane | AssetPane | Assets |
| Interaction_Parts | PartsPane | Parts |
| Designer_ResultsPane | ResultsPane | Results |
Building extensions for Expression Blend 4 using MEF
Introduction
Although it was possible to write extensions for Expression Blend and Expression Design, it wasn’t very easy and out of the box only one addin could be used. With Expression Blend 4 it is possible to write extensions using MEF, the Managed Extensibility Framework.
Until today there’s no documentation on how to build these extensions, so look thru the code with Reflector is something you’ll have to do very often. Because Blend and Design are build using WPF searching the visual tree with Snoop and Mole belong to the tools you’ll be using a lot exploring the possibilities.
Scott Barnes has written an article on his blog about How to hack Expression Blend. It provides some information on how to get to know more about the inside of Blend.
Configuring the extension project
Extensions are regular .NET class libraries. To create one, load up Visual Studio 2010 and start a new project. Because Blend is build using WPF, choose a WPF User Control Library from the Windows section and give it a name and location. I named mine DemoExtension1.
Because Blend looks for addins named *.extension.dll you’ll have to tell Visual Studio to use that in the Assembly Name. To change the Assembly Name right click your project and go to Properties. On the Application tab, add .Extension to name already in the Assembly name text field.![]()
To be able to debug this extension, I prefer to set the output path on the Build tab to the extensions folder of Expression Blend. This means that everything that used to go into the Debug folder is placed in the extensions folder. Including all referenced assemblies that have the copy local property set to false.
One last setting. To be able to debug your extension you could start Blend and attach the debugger by hand. I like it to be able to just hit F5. Go to the Debug tab and add the the full path to Blend.exe in the Start external program text field.![]()
Extension Class
Add a new class to the project. This class needs to be inherited from the IPackage interface. The IPackage interface can be found in the Microsoft.Expression.Extensibility namespace. To get access to this namespace add Microsoft.Expression.Extensibility.dll to your references. This file can be found in the same folder as the (Expression Blend 4 Beta) Blend.exe file. Make sure the Copy Local property is set to false in this reference. After implementing the interface the class would look something like:
using Microsoft.Expression.Extensibility;
namespace DemoExtension1
{
public class DemoExtension1:IPackage
{
public void Load(IServices services)
{
}
public void Unload()
{
}
}
}
These two methods are called when your addin is loaded and unloaded. The parameter passed to the Load method, IServices services, is your main entry point into Blend. The IServices interface exposes the GetService<T> method. You will be using this method a lot. Almost every part of Blend can be accessed thru a service. For example, you can use to get to the commanding services of Blend by calling GetService<ICommandService>() or to get to the Windowing services by calling GetService<IWindowService>().
To get Blend to load the extension we have to implement MEF. (You can get up to speed on MEF on the community site or read the blog of Mr. MEF, Glenn Block.) In the case of Blend extensions, all that needs to be done is mark the class with an Export attribute and pass it the type of IPackage. The Export attribute can be found in the System.ComponentModel.Composition namespace which is part of the .NET 4 framework. You need to add this to your references.
using System.ComponentModel.Composition;
using Microsoft.Expression.Extensibility;
namespace DemoExtension1
{
[Export(typeof(IPackage))]
public class DemoExtension1:IPackage
{
Blend is able to find your addin now.
Adding UI
The addin doesn’t do very much at this point. The WPF User Control Library came with a UserControl so lets use that in this example. I just drop a Button and a TextBlock onto the surface of the control to have something to show in the demo.![]()
To get the UserControl to work in Blend it has to be registered with the WindowService. Call GetService<IWindowService>() on the IServices interface to get access to the windowing services. To get access to the IWindowService interface, add a reference to Microsoft.Expression.Framework to the project. The UserControl will be used in Blend on a Palette and has to be registered to enable it. This is done by calling the RegisterPalette on the IWindowService interface and passing it an identifier, an instance of the UserControl and a caption for the palette.
public void Load(IServices services)
{
IWindowService windowService = services.GetService<IWindowService>();
UserControl1 uc = new UserControl1();
windowService.RegisterPalette("DemoExtension", uc, "Demo Extension");
}
After hitting F5 to start debugging Expression Blend will start. You should be able to find the addin in the Window menu now.
Activating this window will show the “Demo Extension” palette with the UserControl, style according to the settings of Blend.![]()
Now what?
Because little is publicly known about how to access different parts of Blend adding breakpoints in Debug mode and browsing thru objects using the Quick Watch feature of Visual Studio is something you have to do very often. This demo extension can be used for that purpose very easily.
Add the click event handler to the button on the UserControl. Change the contructor to take the IServices interface and store this in a field. Set a breakpoint in the Button_Click method.
public partial class UserControl1 : UserControl
{
private readonly IServices _services;
public UserControl1(IServices services)
{
_services = services;
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
}
}
Change the call to the constructor in the load method and pass it the services property.
public void Load(IServices services)
{
IWindowService service = services.GetService<IWindowService>();
UserControl1 uc = new UserControl1(services);
service.RegisterPalette("DemoExtension", uc, "Demo Extension");
}
Hit F5 to compile and start Blend. Got to the window menu and start show the addin. Click on the button to hit the breakpoint. Now place the carrot text _services text in the code window and hit Shift+F9 to show the Quick Watch window. Now start exploring and discovering where to find everything you need. ![]()
More Information
The are no official resources available yet. Microsoft has released one extension for expression Blend that is very useful as a reference, the Microsoft Expression Blend® Add-in Preview for Windows® Phone. This will install a .extension.dll file in the extension folder of Blend. You can load this file with Reflector and have a peek at how Microsoft is building his addins.
Conclusion
I hope this gives you something to get started building extensions for Expression Blend. Until Microsoft releases the final version, which hopefully includes more information about building extensions, we’ll have to work on documenting it in the community.

