1.概述

UWP允许开发者通过两种方式创建自定义的控件:UserControl和TemplatedControl(模板化控件)。这个主题主要讲述如何创建和理解模板化控件,目标是能理解模板化控件常见的知识点,并且可以创建扩展性良好的模板化控件。

1.1 ControlTemplate

UWP的控件有很多属性,使用这些属性可以为控件定制不同的外观,例如将Button的Border变粗,Background改为红色等,但通过这种改造控件,能做到的仍十分有限。

通过为控件赋予新的ControlTemplate,可以为控件创建全新的外观。在下面的例子中,通过ControlTemplate将Button改成一个圆形按钮。

<Button Content="Orginal" Margin="0,0,20,0"/>
<Button Content="Custom">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Stroke="DarkOrange" StrokeThickness="3" Fill="LightPink"/>
<ContentPresenter Margin="10,20" Foreground="White"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>

ControlTemplate的内容是定义控件可视结构的XAML。有时,这段XAML的根元素包含VisualStateManager.VisualStateGroups附加属性,用于定义不同状态下控件的外观变化。将ControlTemplate赋值到Control.Template即可改变控件的外观。ControlTemplate的TargetType需要和使用它的控件匹配。

注意:UserControl不能使用ControlTemplate。

1.2 模板化控件

可以使用ControlTemplate的控件即为模板化控件(TemplatedControl),在UWP中,所有派生自Control的控件(除了UserControl)都是模板化控件,例如Button、ComboBox等,它们中的大部分都有默认的ControlTemplate。

模板化控件包含以下两个部分:

  • 代码: 定义控件属性及行为。
  • DefaultStyle: 定义控件属性默认样式,包括属性值及ControlTemplate。可以不存在DefaultStyle,所以某些场合会把模板化控件称为“无外观控件”。

2. 创建第一个模板化控件

下面介绍如何使用VisualStudio在一个新项目中创建一个模板化控件。

如图所示,在“添加新项对”话框中选中TemplatedControl,名称部分输入“MyFirstControl”,点击“添加”后VisualStudio会自动在项目中添加两个文件:MyFirstControl.cs和Themes/Generic.xaml:

2.1 MyFirstControl.cs

public sealed class MyFirstControl : Control
{
public MyFirstControl()
{
this.DefaultStyleKey = typeof(MyFirstControl);
}
}

类文件负责定义控件的结构和行为。MyFirstControl.cs的代码如图所示,只包含一个构造函数及一句 this.DefaultStyleKey = typeof(MyFirstControl)。DefaultStyleKey是用于查找控件样式的键,没有这句代码控件就找不到默认UI。

如果控件需要被继承的话,最好把sealed关键字移除。

2.2 Themes/Generic.xaml

<Style TargetType="local:MyFirstControl" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyFirstControl">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

XAML负责定义控件的外观。在第一次创建控件后VisualStudio会自动创建这个文件,并且插入图中的代码。注意其中两个TargetType="local:MyFirstControl",第一个用于匹配MyFirstControl.cs中的DefaultStyleKey,第二个确定ControlTemplete针对的控件类型。两个都不可以移除。Style的内容是一组Setter的集合,除了Template外,还可以添加其它的Setter指定控件的默认外观。

2.3 使用MyFirstControl

<Page
x:Class="App3.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<local:MyFirstControl />
</Grid>
</Page>

通常情况下MainPage已经引用了local命名控件,所以只需<local:MyFirstControl />这段xaml即可轻松使用刚刚创建好的控件。

2.4 使用Blend修改DefaultStyle

就算经验丰富的开发者仍免不了使用Blend这个工具来编辑Style和ControlTemplate,幸好Blend上手十分简单。

使用Blend打开项目后,在“资源”面板展开Generic.xaml节点,选中MyFirstControl,点击编辑资源:

在“对象与时间线”面板,选中“Style”节点可在右侧“属性”面板编辑Style中除Template以外的属性:

在“Style”节点,右键打开菜单,选中“编辑模版”->“编辑当前项”开始编辑Template,此时左侧“对象与时间线”面板展示Template中的结构:

此后,可在编辑区域的上方选择编辑Style或者编辑Template:

由于这个主题主要目的是介绍模板化控件,所以不会深入讨论Blend的操作。

[UWP]了解模板化控件(1):基础知识的更多相关文章

  1. [UWP]了解模板化控件(4):TemplatePart

    1. TemplatePart TemplatePart(部件)是指ControlTemplate中的命名元素.控件逻辑预期这些部分存在于ControlTemplate中,并且使用protected ...

  2. 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, VerticalAlignment

    [源码下载] 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, Vertical ...

  3. 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项

    [源码下载] 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合 ...

  4. C# 基础知识系列- 16 开发工具篇

    0. 前言 这是C# 基础知识系列的最后一个内容讲解篇,下一篇是基础知识-实战篇.这一篇主要讲解一下C#程序的结构和主要编程工具. 1. 工具 工欲善其事必先利其器,在实际动手之前我们先来看看想要编写 ...

  5. .NET面试题系列[1] - .NET框架基础知识(1)

    很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...

  6. RabbitMQ基础知识

    RabbitMQ基础知识 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然 ...

  7. Java基础知识(壹)

    写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...

  8. selenium自动化基础知识

    什么是自动化测试? 自动化测试分为:功能自动化和性能自动化 功能自动化即使用计算机通过编码的方式来替代手工测试,完成一些重复性比较高的测试,解放测试人员的测试压力.同时,如果系统有不份模块更改后,只要 ...

  9. [SQL] SQL 基础知识梳理(一)- 数据库与 SQL

    SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...

  10. [SQL] SQL 基础知识梳理(二) - 查询基础

    SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...

随机推荐

  1. ReentrantLock获取、释放锁的过程

    看了篇文章,觉得分析得很透彻,其后总结的很到位,地址:http://www.iteye.com/topic/1083832 把获取与释放操作串在一起在简单看一下: 获取锁的时候将当前线程放入同步队列, ...

  2. XCode中设置字体大小

    XCode中设置字体大小 1)打开Preferences,快捷键是“Command + ,”(注意,是三个键,按住command键,然后再快速地按“+”和“,”两个键即可) 2)选择“Fonts &a ...

  3. linux 中c/c++实现终端命令行命令

    在终端中可以从用下面命令获得帮助: man system 在c/c++代码中实现和在终端中输入的命令行一样的效果,以命令(audacious -p &)为例,该代码实现用audacious在后 ...

  4. 快速排序时间复杂度为O(n×log(n))的证明

    快速排序时间复杂度为O(n×log(n))的证明 之前只知道快速排序的平均时间复杂度为O(n×log(n)),最糟糕时复杂度为O(n^2),但却不知道具体原因,今天好好证明一下,最后部分摘自<算 ...

  5. 纯CSS3动画:一棵跳舞的树

    <!DOCTYPE html><head><meta http-equiv="Content-Type" content="text/htm ...

  6. CSS3知识点整理(五)----响应式设计及其他属性

    介绍Media Queries与Responsive设计以及外轮廓属性.resize属性.CSS3生成内容等 学会如何使用CSS3中的Media Queries模块来让一个页面适应不同的终端(或屏幕尺 ...

  7. block、inline、inline-block对比

    display:block 1.block元素会独占一行,多个block元素会各种新起一行.默认情况下,block元素宽度自动填满其父元素容器: 2.block元素可以设置width和height属性 ...

  8. 中国大学MOOC中的后台文件传输

    早期版本的中国大学MOOC一旦被挂起后,应用在完成当前下载任务后无法继续添加新任务,当然也无法将缓存状态写入数据库.这个问题能否顺利解决直接关系到用户体验. 顺便吐槽下,凡是使用了后台文件传输还提示你 ...

  9. 在javascript中关于变量与函数的提升

    在javascript中关于变量与函数的提升 一.简介 在javascript中声明变量与函数的执行步骤: 1.先预解析变量或函数声明代码,会把用var声明的变量或者函数声明的代码块进行提升操作 2. ...

  10. JavaScript内置对象-Object

    ▓▓▓▓▓▓ 大致介绍 JavaScript的简单数据类型包括:Undefined.Null.Boolean.Number.String.JavaScript中这五种基本数据类型不是对象,其他所有值都 ...