Walkthrough: Implementing an Inline Value Editor

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

The extensibility model for the WPF Designer for Visual Studio allows you to create custom value editors for properties in the Properties window at design time. Editors can be either inline editors, which allow you edit values directly in the Properties window, or extended editors, which allow you to provide an additional UI for editing a property outside of the Properties window. To demonstrate how to create an inline editor, this walkthrough provides step-by-step procedures for creating an inline value editor for the Background property of a control.

In this walkthrough, you perform the following tasks:

  • Create a WPF custom control project.

  • Create an inline editor that can be used to edit the property value in the Properties window.

  • Create a class that inherits from PropertyValueEditor that is used to connect the inline editor to the class you want to provide custom editing for.

  • Create a class that implements the IProvideAttributeTable interface to register your new inline editor.

  • Test the inline value editor at design time.

Prerequisites

You need the following components to complete this walkthrough:

  • Visual Studio 2012 RC.

Creating the Custom Control

The first step is to create the project for the custom control. The control is a simple button with small amount of design-time code, which uses the GetIsInDesignMode method to implement a design-time behavior.

To create the custom control

  1. Create a new WPF Custom Control Library project in Visual C# named CustomControlLibrary.

    The code for CustomControl1 opens in the Code Editor.

  2. In the Code Editor for CustomControl1, replace the code in the CustomControlLibrary namespace with the following code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace CustomControlLibrary
    {
        public class CustomControl1 : Button
        {
            public CustomControl1()
            {
                if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                {
                    Content = "In design mode";
                }
            }
        }
    }
    
  3. Set the project's output path to "bin\".

  4. Build the solution.

Creating the Template for the Inline Editor

The inline editor can be created with a XAML data template. This will be a simple drop-down list that displays a list of color choices for the Background property.

To create the template for the inline editor

  1. Add a new WPF Custom Control Library project in Visual C# named CustomControlLibrary.Design to the solution.

    The code for CustomControl1 opens in the Code Editor.

  2. In Solution Explorer, delete the CustomControl1 file from the CustomControlLibrary.Design project.

  3. Add a reference to the following WPF Designer assemblies.

    • Microsoft.Windows.Design.Extensibility

    • Microsoft.Windows.Design.Interaction

  4. Add a reference to the CustomControlLibrary project.

  5. Set the project's output path to "..\CustomControlLibrary\bin\". This keeps the control's assembly and the metadata assembly in the same folder, which enables metadata discovery for designers.

  6. Add a new class named EditorResources to the CustomControlLibrary.Design project.

  7. In the Code Editor for EditorResources, replace the automatically generated code with the following code.

    namespace CustomControlLibrary.Design
    {
        using System;
        using System.Collections.Generic;
        using System.Text;
        using System.Windows;
        public partial class EditorResources : ResourceDictionary
        {
            public EditorResources()
                : base()
            {
                InitializeComponent();
            }
        }
    }
    
  8. From the Project menu, click Add Resource Dictionary.

  9. Name the file EditorResources.xaml and click Add.

  10. In XAML view for EditorResources, replace the automatically generated XAML with the following XAML.

        <ResourceDictionary
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:PropertyEditing="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design.Interaction"
        xmlns:Local="clr-namespace:CustomControlLibrary.Design"
        xmlns:Media="clr-namespace:System.Windows.Media;assembly=PresentationCore"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        x:Class="CustomControlLibrary.Design.EditorResources">
        <DataTemplate x:Key="BrushInlineEditorTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <ComboBox Grid.Column="0" Text="{Binding StringValue}">
                    <ComboBoxItem>Red</ComboBoxItem>
                    <ComboBoxItem>Blue</ComboBoxItem>
                    <ComboBoxItem>Green</ComboBoxItem>
                </ComboBox>
            </Grid>
        </DataTemplate>
    </ResourceDictionary>
    
  11. Build the solution.

Encapsulating the Template and Registering the Inline Editor

Now that you have created the template for your inline editor, you must create a class that inherits PropertyValueEditor to use the template as a custom editor, and you must register the new inline editor.

To encapsulate and register your inline editor

  1. Add a new class named BrushInlineEditor to the CustomControlLibrary.Design project.

  2. In the Code Editor for BrushInlineEditor, replace the automatically generated code with the following code.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using Microsoft.Windows.Design.PropertyEditing;
    
    namespace CustomControlLibrary.Design
    {
        public class BrushInlineEditor : PropertyValueEditor
        {
            private EditorResources res = new EditorResources();
    
            public BrushInlineEditor()
            {
                this.InlineEditorTemplate = res["BrushInlineEditorTemplate"] as DataTemplate;
            }
        }
    }
    
  3. Add a new class named Metadata to the CustomControlLibrary.Design project.

  4. In the Code Editor for Metadata, replace the automatically generated code with the following code.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Windows.Design.Metadata;
    using System.ComponentModel;
    using Microsoft.Windows.Design.PropertyEditing;
    using System.Windows.Media;
    using System.Windows.Controls;
    using System.Windows;
    using CustomControlLibrary;
    
    // The ProvideMetadata assembly-level attribute indicates to designers
    // that this assembly contains a class that provides an attribute table. 
    [assembly: ProvideMetadata(typeof(CustomControlLibrary.Design.Metadata))]
    
    namespace CustomControlLibrary.Design
    {
        // 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();
                    builder.AddCustomAttributes
                        (typeof(CustomControl1),
                        "Background",
                        PropertyValueEditor.CreateEditorAttribute(
                            typeof(BrushInlineEditor)));
    
                    return builder.CreateTable();
                }
            }
        }
    }
    
  5. Build the solution.

Testing the Inline Value Editor

Your inline value editor is now complete and ready to use. All that remains is to test it. To test the inline editor, you will add a WPF application to your project, add the custom control to your WPF application, and view the inline editor in action.

To test the inline value editor

  1. Add a new WPF Application project in Visual C# named DemoApplication to the solution.

    MainWindow.xaml opens in the WPF Designer.

  2. Add a reference to the CustomControlLibrary project.

  3. In XAML view for MainWindow.xaml, replace the automatically generated XAML with the following XAML. This XAML adds a reference to the CustomControlLibrary namespace and adds the CustomControl1 custom control. The button appears in Design view with a red background, indicating that the control is in design mode. If the button does not appear, you might have to click the Information bar at the top of the designer to reload the view.

        <Window x:Class="DemoApplication.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300" xmlns:my="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary">
        <Grid>
            <my:CustomControl1 Margin="30,30,30,30" Name="customControl11"></my:CustomControl1>
        </Grid>
    </Window>
    
  4. In Design view, select the control.

  5. In the Properties window, click the drop-down button next to the Background property. A small list of color choices, representing your new inline editor, is displayed instead of the default list of colors. The color choices are Red, Blue, and Green.

  6. Select a color from the drop-down list. The background of your custom control changes to that color.

Next Steps

For a more involved property editor, see Walkthrough: Implementing a Color Editor, which demonstrates how to create an extended editor.

See Also

Tasks

Walkthrough: Implementing a Color Editor

How to: Create a Value Editor

Other Resources

Creating Custom Editors

WPF Designer Extensibility