Providing Design-time Metadata

[This documentation is for preview only, and is subject to change in later releases. Blank topics are included as placeholders.]

When you author custom design experiences for your WPF or Silverlight control, you deploy them in separate design-time assemblies. You specify how these custom design-time implementations interact with tools, such as Visual Studio and Expression Blend, by creating a table that is populated with metadata attributes.

Design-time Assemblies

When a design tool, such as Visual Studio, opens your custom control's assembly, it also looks for related design-time assemblies. In particular, a design tool looks for the ProvideMetadataAttribute assembly-level attribute. When this attribute is found, the designer searches the assembly for a class that implements the IProvideAttributeTable interface. The designer queries the AttributeTable property of this class for an attribute collection that specifies the design-time behavior. For more information, see Walkthrough: Providing Custom Design-time Metadata and Deploying a Custom Control and Design-time Assemblies.

Attribute Table

The AttributeTable class associates design-time metadata attributes with WPF and Silverlight types. The attribute table specifies a particular design-time implementation for a designable type. For example, if you have a custom AdornerPanel for your control, you add a FeatureAttribute to the attribute table to specify a custom FeatureProvider implementation.

Attribute Table Builder

To create an attribute table, you start by creating an instance of the AttributeTableBuilder class. You add metadata to the attribute table builder by calling the AddCustomAttributes method. When you are finished adding metadata, you produce an attribute table by calling the CreateTable method. The attribute table builder methods support callback delegates, so the creation of the attribute table can be deferred until needed.

The following code shows how to specify a custom adorner implementation by using an attribute table.

' Container for any general design-time metadata to initialize.
' Designers look for a type in the design-time assembly that 
' implements IProvideAttributeTable. If found, designers instantiate
' this class and access its AttributeTable property automatically.
Friend Class Metadata
    Implements IProvideAttributeTable

    ' Accessed by the designer to register any design-time metadata.
    Public ReadOnly Property AttributeTable() As AttributeTable _
        Implements IProvideAttributeTable.AttributeTable
        Get
            Dim builder As New AttributeTableBuilder()

            ' Add the adorner provider to the design-time metadata.
            builder.AddCustomAttributes(GetType(ButtonWithDesignTime), _
                                        New FeatureAttribute(GetType(OpacitySliderAdornerProvider)))

            Return builder.CreateTable()
        End Get
    End Property


End Class
// Container for any general design-time metadata to initialize.
// Designers look for a type in the design-time assembly that 
// implements IProvideAttributeTable. If found, designers instantiate 
// this class and access its AttributeTable property automatically.
internal class Metadata : IProvideAttributeTable
{
    // Accessed by the designer to register any design-time metadata.
    public AttributeTable AttributeTable
    {
        get 
        {
            AttributeTableBuilder builder = new AttributeTableBuilder();

            // Add the adorner provider to the design-time metadata.
            builder.AddCustomAttributes(
                typeof(ButtonWithDesignTime),
                new FeatureAttribute(typeof(OpacitySliderAdornerProvider)));

            return builder.CreateTable();
        }
    }
}

For more information, see Walkthrough: Creating a Design-time Adorner.

Basic Design-time Implementation Workflow

You usually follow a similar workflow when you author custom design experiences. For more information, see How to: Deploy a Custom Control and Design-time Assemblies.

For examples that show how to implement custom design-time experiences, see WPF and Silverlight Designer Extensibility Samples.

Advantages of Separate Design-time Assemblies

The WPF Designer for Visual Studio framework decouples design-time metadata from implementation. Separating metadata from the control's run-time code is an important design principle for the following reasons.

  • Build turn-around and integration logistics between teams can make compiling metadata into the control cumbersome.

  • Compiling metadata into the control prevents external tools, such as the WPF Designer or Expression Blend, from modifying that metadata later. This is a key issue for agility. Without decoupling design-time metadata from the control, Visual Studio cannot version its designers without requiring a new version of the .NET Framework.

  • Compiling metadata into the control significantly increases the size of the control assembly. The design-time attributes also slow down the control. Control features, such as data binding, which uses reflection, are affected as additional attributes are loaded into memory.

  • Design-time metadata provides the "personality" of the designer. The features of a designer are largely tied to the application which hosts it, not the control. WPF Designer and Expression Blend use different sets of metadata to provide a feature set that is targeted at a specific type of user.

See Also

Tasks

How to: Deploy a Custom Control and Design-time Assemblies

Reference

AttributeTable

ProvideMetadataAttribute

Concepts

Deploying a Custom Control and Design-time Assemblies

Other Resources

Basic Extensibility Concepts

Understanding WPF Designer Extensibility