Extending Expression Blend 4 & Blend for Visual Studio 2012
- by Chris Skardon
Just getting this off the bat, I presume this will also work for Blend 5, but I can’t confirm it… Anyhews, I imagine you’re here because you want to know how to create an addin for Blend, so let’s jump right in there! First, and foremost, we’re going to need to ensure our development environment has the right setup, so the checklist: Visual Studio 2012 Blend for Visual Studio 2012 OK, let’s create a new project (class library, .NET 4.5): Hello.Extension The ‘.Extension’ bit is very very important. The addin will not work unless it is named in this way. You can put whatever you want at the front, but it has to have the extension bit. OK, so now we have a solution with one project. To this project we need to add references to the following things: Microsoft.Expression.Extensibility (from c:\program files\Microsoft Visual Studio 11.0\Blend\ -- x86 folder if you are on an x64 windows install) Microsoft.Expression.Framework (same location as above) PresentationCore PresentationFramework WindowsBase System.ComponentModel.Composition Got them? ACE. Let’s now add a project to contain our control, so, create a new WPF Application project, cunningly named something like ‘Hello.Control’… (I’m creating a WPF application here, because I’m too lazy to dig up the correct references, and this will add all the ones I need ) Once that is created, delete the App.xaml and MainWindow.xaml files, we won’t be needing them. You will also need to change the properties of the project itself, so it is only a class library. Once that is done, let’s add a new UserControl, which will be this: <UserControl x:Class="Hello.Control.HelloControl"
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="300">
<Grid>
<TextBlock Text="HELLO!!!"/>
</Grid>
</UserControl>
Impressive eh?
Now, let’s reference the WPF project from the Extension library. All that’s left now is to code up our extension…
So, add a class to the Extension project (name wise doesn’t matter), and make it implement the IPackage interface from the Microsoft.Expression.Extensibility library:
public class HelloExtension : IPackage { /**/ }
We’ll implement the two methods we need to:
public class HelloExtension : IPackage
{
public void Load(IServices services) { }
public void Unload() { }
}
We’re only really concerned about the Load method in this case, as let’s face it, the extension we have doesn’t need to do a lot to bog off. The interesting thing about the Load method is that it receives an IServices instance. This allows us to get access to all the services that Expression provides, in this case we’re interested in one in particular, the ‘IWindowService’
So, let’s get that bad boy…
private IWindowService _windowService;
public void Load(IServices services)
{
_windowService = services.GetService<IWindowService>();
}
Nailed it… But why? The WindowService allows us to register our UserControl with Blend, which in turn allows people to activate and see it, which is a big plus point. So, let’s do that…
We’ll create an ‘Initialize’ method to create our new control, and add it to the WindowService:
private HelloControl _helloControl;
public void Initialize()
{
_helloControl = new HelloControl();
if (_windowService.PaletteRegistry["HelloPanel"] == null)
_windowService.RegisterPalette("HelloPanel", _helloControl, "Hello Window");
}
First we check that we’re not already registered, and if we’re not we register, the first argument is the identifier used by the service to, well, identify your extension. The second argument is the actual control, the third argument is the name that people will see in the ‘Windows’ menu of Blend itself (so important note here – don’t put anything embarrassing or (need I say it?) sweary…)
There are only two things to do now -
Call ‘Initialize()’ from our Load method, and
Export the class
This is easy money – add [Export(typeof(IPackage))] to the top of our class…
The full code will (should) look like this:
[Export(typeof (IPackage))]
public class HelloExtension : IPackage
{
private HelloControl _helloControl;
private IWindowService _windowService;
public void Load(IServices services)
{
_windowService = services.GetService<IWindowService>();
Initialize();
}
public void Unload()
{
}
public void Initialize()
{
_helloControl = new HelloControl();
if (_windowService.PaletteRegistry["HelloControl"] == null)
_windowService.RegisterPalette("HelloControl", _helloControl, "Hello Window");
}
}
If you build this and copy it to your ‘Extensions’ folder in Blend (c:\program files\microsoft visual studio 11.0\blend\) and start Blend, you should see ‘Hello Window’ listed in the Window menu:
That as they say is it!