演练:在设计时更改属性的行为

[本文档仅供预览,在以后的发行版中可能会发生更改。包含的空白主题用作占位符。]

当您使用扩展性自定义 适用于 Visual Studio 的 WPF 设计器时,通常会创建自定义控件。 有时您需要控件的某一属性在设计时的行为与运行时不同,但仍允许用户正常设置该属性的值。 例如,您希望用户能够将控件的可见属性设置为 false,但该控件仍应在设计时可见。

在本演练中,将创建自定义 Button 并更改 BackgroundContent 属性的行为。 若要完成此操作,需要创建 DesignModeValueProvider 并将它附加到自定义控件。 DesignModeValueProvider 捕获用户所做的属性更改,您将自己的逻辑插入 TranslatePropertyValue 方法中,DesignModeValueProvider 将新值传递到设计器。

重要

使用此技术时,设计器中的属性行为与 XAML 视图中的属性值不匹配。XAML 视图显示用户在设计时输入的值。XAML 视图中的值表示该属性将在运行时展现的行为。

在本演练中,您将执行下列任务:

备注

显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您现用的设置或版本。若要更改设置,请在“工具”菜单上选择“导入和导出设置”。有关更多信息,请参见 Visual Studio 设置

系统必备

您需要以下组件来完成本演练:

  • Visual Studio 2010

创建一个 WPF 自定义控件库项目

创建项目

  1. 使用 Visual Basic 或 Visual C# 新建一个名为 CustomButton 的 WPF 自定义控件库项目。

    CustomControl1 的代码在“代码编辑器”中打开。

  2. 添加对以下程序集的引用。

    • Microsoft.Windows.Design.Extensibility
  3. 在**“解决方案资源管理器”**中,将代码文件的名称更改为 CustomButton.cs 或 CustomButton.vb。

    如果出现消息框,询问是否对此项目中的所有引用执行重命名操作,请单击**“是”**。

  4. 在**“生成”菜单上,单击“生成解决方案”**。

创建自定义 DesignModeValueProvider

在此过程中,您将创建一个自定义 DesignModeValueProvider。 在 TranslatePropertyValue 方法中,更改 ButtonContent 属性,以使它在设计器中显示为大写。 您还可以更改 ButtonBackground 属性,以使它在设计器中显示为默认系统颜色。 这些更改只影响设计器。 在运行时,ContentBackground 属性显示为用户设置的值。

备注

在此过程中,您将创建一个处理两个不同属性的 DesignModeValueProvider。您也可以创建多个 DesignModeValueProvider 对象来处理不同的属性。

创建自定义 DesignModeValueProvider

  1. 将名为 CustomButtonDesignModeValueProvider.cs 或 CustomButtonDesignModeValueProvider.vb 的新类添加到 CustomButton 项目。

    新类将在代码编辑器中打开。

  2. 将下面的命名空间添加到文件的顶部。 替换现有命名空间(如果有)。

    
    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. 编辑 CustomButtonDesignModeValueProvider 类,以便从 DesignModeValueProvider 继承。

    
    Public Class CustomButtonDesignModeValueProvider
        Inherits DesignModeValueProvider
    
    End Class
    
    
    class CustomButtonDesignModeValueProvider : DesignModeValueProvider
    {
    }
    
  4. 向该类添加构造函数。 在该构造函数中标识要捕获的属性。

    
    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. 重写类中的 TranslatePropertyValue 方法。 这是指定属性在运行时的新行为的位置。

    
    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. 在**“生成”菜单上,单击“生成解决方案”**。

创建自定义按钮控件

在此过程中,将创建一个自定义控件。 创建从 Button 继承的简单自定义控件,但不包含其他自定义功能。

创建自定义按钮控件

  1. 在代码编辑器中打开 CustomButton 类。

  2. 将下面的命名空间添加到文件的顶部。 替换现有命名空间(如果有)。

    
    Imports System.Windows.Controls             'Button
    Imports Microsoft.Windows.Design.Features   'Feature
    
    
    using System.Windows.Controls;              //Button
    using Microsoft.Windows.Design.Features;    //Feature
    
  3. 用下面的类替换现有类。

    
    Public Class CustomButton
        Inherits Button
    
        Shared Sub New()
    
        End Sub
    End Class
    
    
    public class CustomButton : Button
    {
        static CustomButton()
        {
        }
    }
    
  4. 在**“生成”菜单上,单击“生成解决方案”**。

将 DesignModeValueProvider 附加到自定义控件

在此过程中,您通过使用 FeatureAttribute 特性将 DesignModeValueProvider 附加到自定义控件。

备注

您还可以通过提供自定义设计时元数据来将 DesignModeValueProvider 附加到自定义控件。有关更多信息,请参见提供设计时元数据

将 DesignModeValueProvider 附加到自定义控件

  1. 在代码编辑器中,定位 CustomButton 类的声明。 其外观应类似于:

    
    Public Class CustomButton
        Inherits Button
    
    
    public class CustomButton : Button
    
  2. 将 Feature 特性添加到类声明中,并指定 DesignModeValueProvider

    <Feature(GetType(CustomButtonDesignModeValueProvider))> _
    Public Class CustomButton
        Inherits Button
    
    [Feature(typeof(CustomButtonDesignModeValueProvider))]
    public class CustomButton : Button
    
  3. 在**“生成”菜单上,单击“生成解决方案”**。

创建测试应用程序

创建测试应用程序

  1. 向解决方案中添加一个名为 CustomButtonTestApplication 的新 WPF 应用程序项目。

    MainWindow.xaml 将在 WPF Designer中打开。

  2. 在**“解决方案资源管理器”中,右击该项目,然后单击“设为启动项目”**。

  3. 在**“项目”菜单上,单击“添加引用”,然后使用“项目”**选项卡添加对 CustomButton 项目的引用。

  4. 在**“生成”菜单上,单击“生成解决方案”**。

测试自定义控件

测试自定义控件

  1. 在 MainWindow.xaml 的 XAML 视图中,将现有 XAML 替换为以下内容:

    <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. 在设计视图中,选择该按钮。 如有必要,请单击设计器顶部的信息栏以重新加载视图。

  3. 在**“属性”窗口中,找到“Background”**属性。

  4. 键入“Red”,然后按 Enter。

    随即会使用代码 Background="Red" 对 XAML 进行更新,但按钮颜色在设计视图中不会发生更改。

  5. 在**“属性”窗口中,找到“Content”**属性。

  6. 键入“Hello World”,然后按 Enter。

    随即会使用内容 Hello World 对 XAML 进行更新,但按钮在设计视图中仍显示文本 HELLO WORLD。

  7. 在**“调试”菜单上,单击“启动调试”**。

    该应用程序启动并且该窗口将显示。 此按钮显示为红色,并且在运行时包含文本 Hello World。

  8. 关闭该窗口。

请参见

任务

如何:在设计时更改属性的行为

如何:确定自定义控件处于设计时还是运行时

概念

提供设计时元数据

其他资源

设计时与运行时行为

了解 WPF 设计器扩展性

WPF 设计器扩展性