Adding design time Property Browsers to a Silverlight custom control
Check out this article and learn how to ad dign timpe Property browsers to a Silverlight custom control.
This tutorial will explain the process of adding Property Browsers to a custom control. This Property Browsers will be available at design time in Expression Blend. A custom control project is necessary to continue with this tutorial.
This tutorial requires a custom control project. Follow the Creating a Silverlight Control using the WEBfactory 2010 Silverlight SDK tutorial to learn how to create a Silverlight custom control.
For the tutorial purposes, we will work on the solution named SilverlightControlLibrary, containing the SampleControl project.
Adding the SilverlightControlLibrary.Expression.Design project to the solution
As the control we are using has three properties (SignalName, ObjectID and SignalPrefix), we will add the Property Browser to the SignalName property. This SignalName Browser will allow the visualization developer to choose the name of the desired signal from a list, and not by typing the name in the SignalName text field.
Adding the Property Browser is done using a Design project. This Design project we will create a complementary Design library that will reside in a sub-folder of the folder containing the control library.
In our SilverlightControlLibrary solution, add a new Class Library project and name it SilverlightControlLibrary.Expression.Design.
Following the naming convention is important! The Expression.Design project must be always named using the Silverlight control library's name and the .Expression.Design ending.
After adding the Expression.Design project to the solution, the most important part is the referencing the right DLL files. In order for the Property Browser to work, add the following references to the new Expression.Design project:
Microsoft.Windows.Design.Extensibility.dll from C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies;
Microsoft.Windows.Design.Interaction.dll from C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies;
WFDesignExtensions.dll from ...\WEBfactory 2010\Silverlight\Standard\Design;
WFDesignExtensions.PropertyEditorsMwd40.dll from ...\WEBfactory 2010\Silverlight\Standard\Design;
System.Windows.dll from C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\;
SilverlightControlLibrary.dll from the solution folder SilverlightControlLibrary\Bin\Debug . If the solution was built under Release, then the folder will be SilverlightControlLibrary\Bin\Release.
The new references added to SilverlightControlLibrary.Expression.Design
Next, in the SilverlightControlLibrary.Expression.Design project, we need to create two Classes: CustomAttributeTableBuilder.cs and MetadataRegistration.cs. Right-click on the SilverlightControlLibrary.Expression.Design project and select Add > Class.... Add the two required classes. The already existing class Class1.cs can be deleted.
Creating the CustomAttributeTableBuilder class
The CustomAttributeTableBuilder.cs class will contain the code that provides the Property Browsers. Before inserting the Property Browsers we must prepare the class and specify from where and how should it get the Property Browsers:
First we must specify the usings:
using System; using System.ComponentModel; using Microsoft.Windows.Design.Metadata; using Microsoft.Windows.Design.PropertyEditing; using WFDesignExtensions;
Make the CustomAttributeTableBuilder class internal and inherit the AttributeTableBuilder base class:
internal class CustomAttributeTableBuilder : AttributeTableBuilder { }
Create the CustomAttributeTableBuilder internal constructor that will hold the property browsers:
internal CustomAttributeTableBuilder() { }
Add the SignalName property browser in the constructor:
internal CustomAttributeTableBuilder() { this.AddMemberAttributes(typeof(SampleControl), "SignalName", new DescriptionAttribute("Gets or sets the signal name."), new DisplayNameAttribute("SignalName"), new CategoryAttribute("Sample Category"), new PropertyOrderAttribute(PropertyOrder.Default), PropertyValueEditor.CreateEditorAttribute(typeof(SignalBrowserEditor))); }
Now create the AddMemberAttributes method and declare the type attributes:
private void AddMemberAttributes(Type type, string memberName, params Attribute[] attribs) { base.AddCallback(type, builder => builder.AddCustomAttributes(memberName, attribs)); }
Also create the AddTypeAttributes method and declare the member attributes:
private void AddTypeAttributes(Type type, params Attribute[] attribs) { base.AddCallback(type, builder => builder.AddCustomAttributes(attribs)); }
Other Property Browsers are also available to be used:
Project Authorizations Editor
this.AddMemberAttributes(typeof(SampleControl), "SecurityAuthorizationName", new DescriptionAttribute("Gets or sets the security authorization name."), new DisplayNameAttribute("SecurityAuthorizationName"), new CategoryAttribute(CommonConstants.DesignerCategory), new PropertyOrderAttribute(PropertyOrder.Default), PropertyValueEditor.CreateEditorAttribute(typeof(ProjectAuthorizationsEditor)));
Symbolic Text Browser Editor
this.AddMemberAttributes(typeof(SampleControl), "SymbolicText", new DescriptionAttribute("Gets or sets the symbolic text."), new DisplayNameAttribute("SymbolicText"), new CategoryAttribute(CommonConstants.DesignerCategory), new PropertyOrderAttribute(PropertyOrder.Default), PropertyValueEditor.CreateEditorAttribute(typeof(SymbolicTextlBrowserEditor)));
Creating the MetadataRegistration class
Next the MetadataRegistration.cs must be edited.
Replace the existing usings with the following:
using Microsoft.Windows.Design.Metadata;
Declare the assembly:
[assembly: ProvideMetadata(typeof(SilverlightControlLibrary.Expression.Design.MetadataRegistration))]
Make the MetadataRegistration class public and inherit the IProvideAttributeTable base class:
public class MetadataRegistration : IProvideAttributeTable { }
Declare a private attributeTable variable of AttributeTable type:
private AttributeTable attributeTable;
Create the public AttributeTable method that will create a new attribute table if none exists:
public AttributeTable AttributeTable { get { if (attributeTable == null) { attributeTable = new CustomAttributeTableBuilder().CreateTable(); } return attributeTable; } }
Using the Property Browsers
Build the solution. After the build is complete, we need to copy some dll files from the build directories in a standard folder structure, that will be recognized by Expression Blend:
From the SilverlightControlLibrary/Bin/Debug copy the SilverlightControlLibrary.dll file to another folder of your choice.
From the SilverlightControlLibrary.Expression.Design/Bin/Debug copy SilverlightControlLibrary.Expression.Design.dll, WFDesignExtensions.dll and WFDesignExtensions.PropertyEditorsMwd40.dll and paste them in a folder named Design, inside the folder where SilverlightControlLibrary.dll is.
In order to use the control and its property browsers in a Expression Blend project, you will need to reference the SilverlightControlLibrary.dll file. The dll files inside the Design folder will be automatically recognized by Expression Blend and used appropriately.