本文介绍如何使用 C# 创建适用于 WinUI 3 的模板化 XAML 控件。 模板化控件继承自 Microsoft.UI.Xaml.Controls.Control,并且具有可使用 XAML 控件模板自定义的可视结构和可视行为。
若要在 C# 中创建独立的 WinUI 3 组件供 C# 和 C++/WinRT 应用使用,请参阅
演练:使用 WinUI 3 控件创建 C# 组件,然后从 C++ Windows App SDK 应用程序使用该组件
一文。
设置开发环境,请参阅
安装适用于 Windows 应用 SDK 的工具
。
按照如何
创建第一个 WinUI 3 项目
的说明进行操作。
创建空白应用 (BgLabelControlApp)
首先在 Microsoft Visual Studio 中创建新项目。 在“新建项目”对话框中,选择“打包的空白应用(桌面版 WinUI 3)”项目模板,并确保选择 C# 语言版本。 将项目名称设置为“BgLabelControlApp”,使文件名与以下示例中的代码保持一致。
向应用添加模板化控件
若要添加模板化控件,请单击工具栏中的“项目”菜单,或在“解决方案资源管理器”中右键单击项目,然后选择“添加新项”。 在“Visual C#”>“WinUI”下,选择“自定义控件(WinUI 3)”模板。 将新控件命名为“BgLabelControl”,然后单击“添加”。
更新自定义控件 C# 文件
在 C# 文件 BgLabelControl.cs 中,请注意,构造函数定义了控件的 DefaultStyleKey 属性。 此键标识默认模板,如果控件的使用者未显式指定模板,则使用该模版。 键值是控件的类型。 稍后,在实现通用模板文件时,我们将看到使用此键。
public BgLabelControl()
this.DefaultStyleKey = typeof(BgLabelControl);
我们的模板化控件将具有一个文本标签,该标签可通过代码、XAML 或通过数据绑定以编程方式设置。 为了使系统保持控件标签的文本为最新,需要将其实现为 DependencyPropety。 为此,我们首先声明一个字符串属性,并将其命名为“Label”。 我们不使用后备变量,而是通过调用 GetValue 和 SetValue 来设置和获取依赖项属性的值。 这些方法由 Microsoft.UI.Xaml.Controls.Control 继承的 DependencyObject 提供。
public string Label
get => (string)GetValue(LabelProperty);
set => SetValue(LabelProperty, value);
接下来,声明该依赖项属性,并通过调用 DependencyProperty.Register 向系统注册它。 此方法指定“Label”属性的名称和类型、该属性所有者的类型、BgLabelControl 类以及该属性的默认值 。
DependencyProperty LabelProperty = DependencyProperty.Register(
nameof(Label),
typeof(string),
typeof(BgLabelControl),
new PropertyMetadata(default(string), new PropertyChangedCallback(OnLabelChanged)));
实现依赖项属性只需要这两个步骤,但在此示例中,我们将为 OnLabelChanged 事件添加一个可选处理程序。 每当该属性值更新时,系统都会引发此事件。 在这种情况下,我们将检查新标签文本是否为空字符串,并相应地更新类变量。
public bool HasLabelValue { get; set; }
private static void OnLabelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
BgLabelControl labelControl = d as BgLabelControl; //null checks omitted
String s = e.NewValue as String; //null checks omitted
if (s == String.Empty)
labelControl.HasLabelValue = false;
labelControl.HasLabelValue = true;
有关依赖项属性工作原理的详细信息,请参阅依赖项属性概述。
定义 BgLabelControl 的默认样式
模板化控件必须提供默认样式模板,如果控件的用户未显示设置样式,则使用该样式模板。 在此步骤中,我们将修改控件的通用模板文件。
当你将自定义控件 (WinUI) 添加到应用时,就会生成通用模板文件。 此文件命名为“Generic.xaml”,并且在解决方案资源管理器的“Themes”文件夹中生成。 为了让 XAML 框架能够找到模板化控件的默认样式,文件夹和文件名是必须的。 删除 Generic.xaml 的默认内容,然后粘贴下方的标记。
<!-- \Themes\Generic.xaml -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BgLabelControlApp">
<Style TargetType="local:BgLabelControl" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:BgLabelControl">
<Grid Width="100" Height="100" Background="{TemplateBinding Background}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{TemplateBinding Label}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
在此示例中,可以看到“Style”元素的“TargetType”属性设置为“BgLabelControlApp”命名空间中的“BgLabelControl”类型 。 此类型的值与前面为控件的构造函数中的“DefaultStyleKey”属性指定的值相同,该构造函数将此值标识为控件的默认样式。
控件模板中“TextBlock”的“Text”属性绑定到控件的“Label”依赖项属性 。 该属性使用 TemplateBinding 标记扩展进行绑定。 此示例还将“Grid”背景绑定到继承自“Control”类的“Background”依赖项属性 。
将 BgLabelControl 的实例添加到主 UI 页面
打开 MainWindow.xaml
,其中包含主 UI 页面的 XAML 标记。 紧接在 Button 元素(StackPanel 内)之后,添加以下标记 。
<local:BgLabelControl Background="Red" Label="Hello, World!"/>
生成并运行该应用,你将看到模板化控件具有我们指定的背景颜色和标签。
Windows 应用 SDK
Windows App SDK 的稳定发布渠道
Windows应用 SDK 示例