Walkthrough: Changing the Behavior of a Property at Design Time

When you use extensibility to customize the WPF Designer for Visual Studio, you often create custom controls. Sometimes you need a property of the control to behave differently at design time than at run time, while still letting the user set the value of the property normally. For example, you want the user to be able to set the visible property of a control to false, but the control should still be visible at design time.

In this walkthrough you create a custom Button and change the behavior of the Background and Content properties. To accomplish this, you create a DesignModeValueProvider and attach it to your custom control. The DesignModeValueProvider captures property changes that the user makes, you insert your own logic in the TranslatePropertyValue method, and the DesignModeValueProvider passes the new values to the designer.

Important

When you use this technique, the behavior of a property in the designer does not match the value of the property in XAML view. XAML view displays the value that the user entered at design time. The value in XAML view represents the behavior that the property will exhibit at run time.

In this walkthrough, you perform the following tasks:

Note

The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings or edition. To change your settings, choose Import and Export Settings on the Tools menu. For more information, see Working with Settings.

Prerequisites

You need the following components to complete this walkthrough:

  • Visual Studio 2010

Creating a WPF Custom Control Library Project

To create the project

  1. Create a new WPF Custom Control Library project in Visual Basic or Visual C# named CustomButton.

    The code for CustomControl1 opens in the Code Editor.

  2. Add a reference to the following assembly.

    • Microsoft.Windows.Design.Extensibility
  3. In Solution Explorer, change the name of the code file to CustomButton.cs or CustomButton.vb.

    If a message box appears that asks if you want to perform a rename for all references in this project, click Yes.

  4. On the Build menu, click Build Solution.

Creating a Custom DesignModeValueProvider

In this procedure you create a custom DesignModeValueProvider. In the TranslatePropertyValue method, you change the Content property of the Button so that it appears uppercase in the designer. You also change the Background property of the Button so that it appears with the default system color in the designer. These changes affect the designer only. At run time, the Content and the Background properties appear with the values set by the user.

Note

In this procedure, you create one DesignModeValueProvider that handles two different properties. You can also create multiple DesignModeValueProvider objects to handle different properties.

To create a custom DesignModeValueProvider

  1. Add a new class named CustomButtonDesignModeValueProvider.cs or CustomButtonDesignModeValueProvider.vb to the CustomButton project.

    The new class opens in the Code Editor.

  2. Add the following namespaces to the top of the file. Replace the existing ones if there are any.

    
    Imports System
    Imports System.Windows                  'SystemColors
    Imports System.Windows.Media            'SolidColorBrush
    Imports System.Windows.Controls         'Button
    Imports Microsoft.Windows.Design.Model  'DesignModeValueProvider
    Imports Microsoft.Windows.Design.Metadata
    
    
    
    using System;
    using System.Windows;                   //SystemColors
    using System.Windows.Media;             //SolidColorBrush
    using System.Windows.Controls;          //Button
    using Microsoft.Windows.Design.Model;
    using Microsoft.Windows.Design.Metadata;   //DesignModeValueProvider
    
  3. Edit the CustomButtonDesignModeValueProvider class to inherit from the DesignModeValueProvider.

    
    Public Class CustomButtonDesignModeValueProvider
        Inherits DesignModeValueProvider
    
    End Class
    
    
    class CustomButtonDesignModeValueProvider : DesignModeValueProvider
    {
    }
    
  4. Add a constructor to the class. In the constructor you identify the properties that you want to capture.

    
    Public Sub New()
        Properties.Add(GetType(Button), "Content")
        Properties.Add(GetType(Button), "Background")
    End Sub
    
    
    public CustomButtonDesignModeValueProvider()
    {
        Properties.Add( typeof(Button), "Content");
        Properties.Add(typeof(Button), "Background");
    }
    
  5. Override the TranslatePropertyValue method in the class. This is where you specify the new behavior of the properties at design time.

    
    Public Overrides Function TranslatePropertyValue( _
        ByVal item As ModelItem, _
        ByVal identifier As PropertyIdentifier, _
        ByVal value As Object) As Object
    
        If identifier.DeclaringType Is GetType(Button) And _
           identifier.Name = "Content" Then
    
            Return value.ToString().ToUpper()
        End If
    
        If identifier.DeclaringType Is GetType(Button) And _
           identifier.Name = "Background" Then
    
            Return New SolidColorBrush(SystemColors.ControlColor)
        End If
    
        Return MyBase.TranslatePropertyValue(item, identifier, value)
    End Function
    
    
    public override object TranslatePropertyValue(ModelItem item, PropertyIdentifier identifier, object value)
    {
        if (identifier.DeclaringType == typeof( Button ) &&
            identifier.Name == "Content" )
        {
            return ((string)value).ToUpper();
        }
    
        if (identifier.DeclaringType == typeof(Button) &&
            identifier.Name == "Background")
        {
            return new SolidColorBrush(SystemColors.ControlColor);
        }
    
        return base.TranslatePropertyValue(item, identifier, value);
    }
    
  6. On the Build menu, click Build Solution.

Creating a Custom Button Control

In this procedure you create the custom control. You create a simple custom control that inherits from Button, but contains no additional custom functionality.

To create a custom button control

  1. Open the CustomButton class in the Code Editor.

  2. Add the following namespaces to the top of the file. Replace the existing ones if there are any.

    
    Imports System.Windows.Controls             'Button
    Imports Microsoft.Windows.Design.Features   'Feature
    
    
    using System.Windows.Controls;              //Button
    using Microsoft.Windows.Design.Features;    //Feature
    
  3. Replace the existing class with the following.

    
    Public Class CustomButton
        Inherits Button
    
        Shared Sub New()
    
        End Sub
    End Class
    
    
    public class CustomButton : Button
    {
        static CustomButton()
        {
        }
    }
    
  4. On the Build menu, click Build Solution.

Attaching the DesignModeValueProvider to the Custom Control

In this procedure you attach the DesignModeValueProvider to the custom control using the FeatureAttribute attribute.

Note

You can also attach a DesignModeValueProvider to a custom control by using the providing custom design-time metadata. For more information, see Providing Design-time Metadata.

To attach the DesignModeValueProvider to the custom control

  1. In the Code Editor, locate the declaration for the CustomButton class. It should look like the following:

    
    Public Class CustomButton
        Inherits Button
    
    
    public class CustomButton : Button
    
  2. Add a Feature attribute to the class declaration, and specify the DesignModeValueProvider.

    <Feature(GetType(CustomButtonDesignModeValueProvider))> _
    Public Class CustomButton
        Inherits Button
    
    [Feature(typeof(CustomButtonDesignModeValueProvider))]
    public class CustomButton : Button
    
  3. On the Build menu, click Build Solution.

Creating a Test Application

To create a test application

  1. Add a new WPF Application project named CustomButtonTestApplication to the solution.

    MainWindow.xaml opens in the WPF Designer.

  2. In Solution Explorer, right-click the project and then click Set as StartUp Project.

  3. On the Project menu, click Add Reference, and use the Projects tab to add a reference to the CustomButton project.

  4. On the Build menu, click Build Solution.

Testing the Custom Control

To test the custom control

  1. In XAML view for MainWindow.xaml, replace the existing XAML with the following:

    <Window x:Class="CustomButtonTestApplication.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cb="clr-namespace:CustomButton;assembly=CustomButton"
        Title="MainWindow" Height="300" Width="300">
        <Grid>
            <cb:CustomButton Height="75" Width="100">Button1</cb:CustomButton>
        </Grid>
    </Window>
    
  2. In Design view, select the button. If necessary, click the Information bar at the top of the designer to reload the view.

  3. In the Properties window, locate the Background property.

  4. Type in Red and press Enter.

    The XAML is updated with the code Background="Red", but the color of the button does not change in Design view.

  5. In the Properties window locate the Content property.

  6. Type in Hello World and press Enter.

    The XAML is updated with the content Hello World, but the button displays the text HELLO WORLD in Design view.

  7. On the Debug menu, click Start Debugging.

    The application starts and the window appears. The button is red and contains the text Hello World at run time.

  8. Close the window.

See Also

Tasks

How to: Change the Behavior of a Property at Design Time

How to: Determine if a Custom Control is in Design Time or Run Time

Concepts

Providing Design-time Metadata

Other Resources

Design Time versus Run Time Behavior

Understanding WPF Designer Extensibility

WPF Designer Extensibility