演练:在设计时更改属性的行为
[本文档仅供预览,在以后的发行版中可能会发生更改。包含的空白主题用作占位符。]
当您使用扩展性自定义 适用于 Visual Studio 的 WPF 设计器时,通常会创建自定义控件。 有时您需要控件的某一属性在设计时的行为与运行时不同,但仍允许用户正常设置该属性的值。 例如,您希望用户能够将控件的可见属性设置为 false,但该控件仍应在设计时可见。
在本演练中,将创建自定义 Button 并更改 Background 和 Content 属性的行为。 若要完成此操作,需要创建 DesignModeValueProvider 并将它附加到自定义控件。 DesignModeValueProvider 捕获用户所做的属性更改,您将自己的逻辑插入 TranslatePropertyValue 方法中,DesignModeValueProvider 将新值传递到设计器。
重要
使用此技术时,设计器中的属性行为与 XAML 视图中的属性值不匹配。XAML 视图显示用户在设计时输入的值。XAML 视图中的值表示该属性将在运行时展现的行为。
在本演练中,您将执行下列任务:
创建一个 WPF 自定义控件库项目。
创建自定义 DesignModeValueProvider。
创建自定义按钮控件。
将 DesignModeValueProvider 附加到自定义控件。
创建测试应用程序。
测试自定义控件。
备注
显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您现用的设置或版本。若要更改设置,请在“工具”菜单上选择“导入和导出设置”。有关更多信息,请参见 Visual Studio 设置。
系统必备
您需要以下组件来完成本演练:
- Visual Studio 2010
创建一个 WPF 自定义控件库项目
创建项目
使用 Visual Basic 或 Visual C# 新建一个名为 CustomButton 的 WPF 自定义控件库项目。
CustomControl1 的代码在“代码编辑器”中打开。
添加对以下程序集的引用。
- Microsoft.Windows.Design.Extensibility
在**“解决方案资源管理器”**中,将代码文件的名称更改为 CustomButton.cs 或 CustomButton.vb。
如果出现消息框,询问是否对此项目中的所有引用执行重命名操作,请单击**“是”**。
在**“生成”菜单上,单击“生成解决方案”**。
创建自定义 DesignModeValueProvider
在此过程中,您将创建一个自定义 DesignModeValueProvider。 在 TranslatePropertyValue 方法中,更改 Button 的 Content 属性,以使它在设计器中显示为大写。 您还可以更改 Button 的 Background 属性,以使它在设计器中显示为默认系统颜色。 这些更改只影响设计器。 在运行时,Content 和 Background 属性显示为用户设置的值。
备注
在此过程中,您将创建一个处理两个不同属性的 DesignModeValueProvider。您也可以创建多个 DesignModeValueProvider 对象来处理不同的属性。
创建自定义 DesignModeValueProvider
将名为 CustomButtonDesignModeValueProvider.cs 或 CustomButtonDesignModeValueProvider.vb 的新类添加到 CustomButton 项目。
新类将在代码编辑器中打开。
将下面的命名空间添加到文件的顶部。 替换现有命名空间(如果有)。
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
编辑 CustomButtonDesignModeValueProvider 类,以便从 DesignModeValueProvider 继承。
Public Class CustomButtonDesignModeValueProvider Inherits DesignModeValueProvider End Class
class CustomButtonDesignModeValueProvider : DesignModeValueProvider { }
向该类添加构造函数。 在该构造函数中标识要捕获的属性。
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"); }
重写类中的 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); }
在**“生成”菜单上,单击“生成解决方案”**。
创建自定义按钮控件
在此过程中,将创建一个自定义控件。 创建从 Button 继承的简单自定义控件,但不包含其他自定义功能。
创建自定义按钮控件
在代码编辑器中打开 CustomButton 类。
将下面的命名空间添加到文件的顶部。 替换现有命名空间(如果有)。
Imports System.Windows.Controls 'Button Imports Microsoft.Windows.Design.Features 'Feature
using System.Windows.Controls; //Button using Microsoft.Windows.Design.Features; //Feature
用下面的类替换现有类。
Public Class CustomButton Inherits Button Shared Sub New() End Sub End Class
public class CustomButton : Button { static CustomButton() { } }
在**“生成”菜单上,单击“生成解决方案”**。
将 DesignModeValueProvider 附加到自定义控件
在此过程中,您通过使用 FeatureAttribute 特性将 DesignModeValueProvider 附加到自定义控件。
备注
您还可以通过提供自定义设计时元数据来将 DesignModeValueProvider 附加到自定义控件。有关更多信息,请参见提供设计时元数据。
将 DesignModeValueProvider 附加到自定义控件
在代码编辑器中,定位 CustomButton 类的声明。 其外观应类似于:
Public Class CustomButton Inherits Button
public class CustomButton : Button
将 Feature 特性添加到类声明中,并指定 DesignModeValueProvider。
<Feature(GetType(CustomButtonDesignModeValueProvider))> _ Public Class CustomButton Inherits Button
[Feature(typeof(CustomButtonDesignModeValueProvider))] public class CustomButton : Button
在**“生成”菜单上,单击“生成解决方案”**。
创建测试应用程序
创建测试应用程序
向解决方案中添加一个名为 CustomButtonTestApplication 的新 WPF 应用程序项目。
MainWindow.xaml 将在 WPF Designer中打开。
在**“解决方案资源管理器”中,右击该项目,然后单击“设为启动项目”**。
在**“项目”菜单上,单击“添加引用”,然后使用“项目”**选项卡添加对 CustomButton 项目的引用。
在**“生成”菜单上,单击“生成解决方案”**。
测试自定义控件
测试自定义控件
在 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>
在设计视图中,选择该按钮。 如有必要,请单击设计器顶部的信息栏以重新加载视图。
在**“属性”窗口中,找到“Background”**属性。
键入“Red”,然后按 Enter。
随即会使用代码 Background="Red" 对 XAML 进行更新,但按钮颜色在设计视图中不会发生更改。
在**“属性”窗口中,找到“Content”**属性。
键入“Hello World”,然后按 Enter。
随即会使用内容 Hello World 对 XAML 进行更新,但按钮在设计视图中仍显示文本 HELLO WORLD。
在**“调试”菜单上,单击“启动调试”**。
该应用程序启动并且该窗口将显示。 此按钮显示为红色,并且在运行时包含文本 Hello World。
关闭该窗口。