WPF——Control与Template理解

news2024/11/25 12:54:11

文章目录

  • 一、前言
  • 二、控件
  • 三、模板
    • 3.1 DataTemplate
    • 3.2 ControlTemplate
    • 3.3 ContentPresenter
  • 四、结语


一、前言

最近又翻看了下刘铁猛的《深入浅出WPF》,发现对模板章节中的部分内容有了更深的体会,所以写篇文扯扯。

文章标题是Control与Template,翻译成控件与模板。
将两者放一起不是无缘无故的,在WPF中,两者关系相当密切。


二、控件

如果有人问你什么是控件,你会怎么回答?
像界面上的按钮、文本框、滚动条啊,都是控件。
所以控件可以理解为界面的组成元素。

以上是我之前的回答,这样的回答没啥问题,很直观,很多人听了都能明白,虽然可能不太严谨。

不过如果继续问,
那为什么叫控件,而不是其它名称。这种界面上的可交互的图案,称作图形元素,不是更直观、更贴切?

我可能会回答,控件这个名称是根据Control这个单词翻译过来的,所以叫控件。

对面可能继续问,那为什么英文叫Control,而不是Graphic Element。
此时我陷入了沉思,确实,为什么会用Control这个单词来命名呢。

如何消除这个疑惑,最简单的就是百度,

百度词条
控件是指对数据和方法的封装
控件可以有自己的属性和方法,其中属性是控件数据的简单访问者,方法则是控件的一些简单而可见的功能、控件创建过程包含设计、开发、调试工作,然后是控件的使用。

先别管百度说的是对是错,但显然并不直观。你跟非程序员这么解释,他可能还是不懂。

那么从专业的角度来看,这段对控件的描述有没有道理呢。
学过程序的都知道,程序的本质是数据结构与算法

界面上的控件呈现了一定内容,并且提供了一些交互方式,用户通过交互可以改变程序状态。

那么,控件呈现的内容本质是什么?
是数据。
控件提供的交互方式本质/目的是什么?
我想应该是程序逻辑,比如你按下按钮,最终程序内部会执行一个方法(一段代码,即程序逻辑),程序状态可能会因此发生一些改变。

所以,控件既是数据的表现形式,以让用户可以直观地看到数据;又是算法的表现形式,以让用户方便地操作逻辑

作为“表现形式”,每个控件都是为了实现某种用户操作算法和直观显示某种数据而生的,一个控件看上去是什么样子由它的“算法内容”和“数据内容”决定,这也是哲学中常说的内容决定形式

这样看来,百度的这段话还是挺有道理的,更接近控件的本质。


三、模板

接下来回到WPF中的模板。

在以往的GUI技术中,控件内部的逻辑和数据是固定的,程序员不能改变(比如WinForms/Qt(QWidget));对于控件的外观,程序员能做的改变也非常有限,一般就是设置控件的属性,想改变控件的内部结构更是不可能。如果想扩展一个控件的功能或更改其外观让其更适合业务逻辑,哪怕只有一丁点改变,也经常要创建控件的子类或创建用户控件(UserControl)。造成这个局面的根本原因就是数据和算法的“形式”与“内容”耦合的太紧了

在WPF中,通过引入模板(Template),将数据和算法的“内容”和“形式”解耦了。

WPF中的Template分为两大类:

  • ControlTemplate,是算法内容的表现形式,一个控件怎样组织其内部结构才能让它更符合业务逻辑、让用户操作起来更舒服就是由它来控制的。它决定了控件“长成什么样子”,并让程序员有机会在控件原有的内部逻辑基础上扩展自己的逻辑。
  • DataTemplate,是数据内容的表现形式,一条数据显示成什么样子,是简单文本还是直观的图形动画就由它来决定。

一言蔽之,Template就是“外衣”——ControlTemplate是控件的外衣,DataTemplate是数据的外衣。

WPF中的控件不再具有固定的形象,仅仅是算法内容和数据内容的载体。
你可以把控件理解为一组操作逻辑穿上了一套衣服,换套衣服就能变成另外一个模样。你看到的控件默认形象实际上就是出厂时微软为它穿上的默认服装。

3.1 DataTemplate

在实际项目中,DataTemplate相较于ControlTemplate,往往是用的比较多一些。

正如其名,它是数据的模板/外观。使用时,往往会在外层绑上一个对象,然后在内部将对象的属性绑定到各种控件。

只要将绑定的控件更换,显示的外观也会发生变化。即一样的内容可以用不同形式来展现,软件设计称之为“数据-视图”(Data-View)模式

在WPF开发中,DataTemplate常用的地方有三处,分别是:

  • ContentControl的ContentTemplate属性,相当于给ContentControl的内容穿衣服。
  • ItemsControl的ItemTemplate属性,相当于给ItemsControl的数据项穿衣服。
  • GridViewColumn的CellTemplate属性,相当于给GridViewColumn单元格里的数据穿衣服。

3.2 ControlTemplate

前面说过,
你看到的控件默认形象实际上就是出厂时微软为它穿上的默认服装。
因为ControlTemplate有默认服装,且大部分时候默认服装已经够用了,所以很少有人会手动去修改它。

实际项目中,即使要给ControlTemplate做替换,也往往是用成熟的UI工具包,引入项目中,应用其样式即可。

这很合理,前面也说了,每个控件都是为了实现某种用户操作算法和直观显示某种数据而生的。而这些特定的操作算法是由控件的本质决定的,显然这部分内容较数据来讲是更为固定,交由微软或者专业的组件开发商决定没有问题。

不过,这也并不意味着普通程序员就完全不需要去了解ControlTemplate。因为某些时候,确实也会需要修改它们。

《WPF深入浅出》一书中说到,

实际项目中,ControlTemplate主要由两大用处:

  1. 通过更换ControlTemplate改变控件外观,使之具有更优的用户体验及外观。
  2. 接触ControlTemplate,程序员与设计师可以并行工作,程序员可以先用WPF标准控件进行编程,等设计师工作完成后,只需把新的ControlTemplate应用到程序中就可以了。

不过考虑到国内WPF开发的现状,应该很少有设计师和程序员工作完全分离的。所以ControlTemplate的使用上也集中在第一点了。

但第一点,听起来似乎和之前所说的冲突了,ControlTemplate不是呈现算法的吗,怎么变成改变控件外观的了。

其实这并不矛盾,因为控件的外观和控件的本质息息相关。

  • Button为什么形状都差不多,一般就是一个椭圆或矩形,可点击,点击后会凹下去。
  • TextBox为什么都是一个矩形框,里面可输入文字。
  • ScrollBar为什么都是一个长条,你可以拖动它移动。

还记得算法是什么吗?
每本编程入门书都会说,算法是解决问题的办法。

这些控件之所以有这样的外观和交互方式,并不是凭空产生的,而是人设计出来的。显然这样的设计就是为了解决一类问题,即它是一种算法。

当你对控件效果不满意时,就可能需要更改其外观,以贴合实际需求。

此时,我对ControlTemplate又有了一层理解。控件模板描述的是控件外观以及外观对外界刺激所做出的反应(比如各种事件/按钮鼠标触摸后的背景色变化等),而外观和对刺激的反应更深层的含义是该类控件要解决的问题的解决方案

下面是一个实际开发中的ControlTemplate应用场景,我需要在鼠标移动到按钮上时,按钮的背景色发生变红色(这是为了使鼠标移动到按钮的操作有反馈感):

<Style TargetType="Button">
   <Style.Triggers>
       <Trigger Property="IsMouseOver" Value="True">
           <Setter Property="Template">
               <Setter.Value>
                   <ControlTemplate TargetType="Button">
                       <Border Background="red">
                           <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
                       </Border>
                   </ControlTemplate>
               </Setter.Value>
           </Setter>
       </Trigger>
   </Style.Triggers>
</Style>

如代码所示,用触发器检验鼠标是否在控件上,若是则修改其控件模板,主要就是将控件模板外的border的背景色变红。

3.3 ContentPresenter

实际上Button的结构就是这么简单,
在这里插入图片描述

<Border>
	<ContentPresenter/>
</Border>

一个边框加一个ContentPresenter就组成了一个按钮。
那么,ContentPresenter是什么?
我们可以通过反编译看到其中结构,下面是我整理出来的一个类关系图:

在这里插入图片描述
你会发现ContentPresenter的结构和ContentControl高度重合。
这边我也不卖关子,也不想花太多篇幅去深究它们的关系。
你可以把ContentPresenter直接理解成控件的数据内容模板DataTemplate。

有的控件继承了ContentControl,我称之为内容控件。
也有部分控件没有继承它,比如TextBox,
在这里插入图片描述

也因此,TextBox的默认控件模板中不存在ContentPresenter。这也很好理解,都没有数据内容,何来数据内容呈现?

你可能会问,那它的Text属性不是数据内容?
当然是,但从控件的角度来看,Text这样的属性已经是相当基础了,就是一段字串(有点类似于“原子数据”),而内容控件的Content可能是有分割必要的,比如Button中可能会有文字描述/图标等。因此我个人倾向于,Text本身这种简单的特性导致了它不作为内容模板出现。


四、结语

写了这么多,主要就是谈了谈对控件以及两个模板的理解。
这种理解更像是WPF开发(也不限于WPF)的内功,不对写代码直接产生效率提升,但会有长远的积极影响。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1004052.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

画流程图用什么软件好?安利这几款

画流程图用什么软件好&#xff1f;画流程图是一项非常重要的技能&#xff0c;它可以帮助我们更好地规划和管理工作流程&#xff0c;提高工作效率。在现代的企业中&#xff0c;流程图已经成为了不可或缺的一部分&#xff0c;它可以用来描述各种业务流程、流程控制、组织结构等等…

数据治理实战步骤

写在前面:数据治理是数字化转型的基础,是数字要素流通的首要任务。但是面对不同的情况,数据治理的手段不同。 数据治理专员要转换思想,数据治理中单靠技术、软件是不行的,比如一些单位认为数据治理平台是万能的,直接上平台一般是做不好的,需基于企业的组织文化、愿景等对…

vue全局使用sass变量

需求&#xff1a;框架需要使用scss&#xff0c;之后不想把很多重复的css一个一个写&#xff0c;就提取出来咯&#xff0c;到时候只需要更改scss文件就可以了&#xff0c;不用一个一个的找 1.下载sass 这我下的俩个版本&#xff0c;如果你们下载最新版不兼容可以参考我的版本下…

高效办公利器:批量重命名与翻译文件名一步到位

在我们的日常工作中&#xff0c;我们经常需要处理大量的文件&#xff0c;包括图片、文档、视频等各种类型。有时候&#xff0c;我们需要对文件进行重命名或者翻译&#xff0c;以便于我们更方便地管理和使用这些文件。但是&#xff0c;如果一个一个手动操作&#xff0c;将是非常…

《树莓派4B家庭服务器搭建指南》第二十一期:安装开源远程桌面服务rustdesk, 内网丝滑,外网流畅控制

title: 《树莓派4B家庭服务器搭建指南》第二十一期&#xff1a;安装开源远程桌面服务rustdesk, 内网丝滑,外网流畅控制Windows,macOS,Linux设备 tags: 个人成长 categories:树莓派不吃灰 前段时间, 有一台老式MacBook Pro被我改造成了影视资源解码主机, 《树莓派4B家庭服务器搭…

老师怎样发布查询

作为一名老师&#xff0c;我们经常需要向家长发布各种查询&#xff0c;比如成绩查询、作业查询等。以往&#xff0c;我们可能会将查询结果整理成Excel表格&#xff0c;然后通过各种渠道发送给家长&#xff0c;这样既繁琐又不够高效。幸好&#xff0c;现在有了易查分&#xff0c…

MybatisPlus(4)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 在之前我们讲解了大部分查询相关的操作&#xff0c;接下来进行增删改的学…

SpringBoot项目--电脑商城【增加/减少购物车商品数量】

1.持久层[Mapper] 1.1规划需要执行的SQL语句 1.更新该商品的数量.此SQL语句无需重复开发 update t_cart set num?,modified_user?,modified_time? where cid? 2.首先进行查询需要操作的购物车数据信息【查看该条数据是否存在】 SELECT * FROM t_cart WHERE cid?2.接口…

如何解决实时语音通讯技术的延迟问题?

实时语音通讯技术的延迟问题一直是人们关注的焦点。在实时通讯中&#xff0c;延迟会影响到通话的质量和用户体验&#xff0c;因此如何解决实时语音通讯技术的延迟问题是一个重要的挑战。本文将探讨如何解决实时语音通讯技术的延迟问题。 一、延迟的定义和分类 延迟是指从说话…

C语言和汇编到底谁更厉害呢?

今日话题&#xff0c;C语言和汇编到底谁更厉害呢&#xff1f; 有位毕业生与我分享了他的经历。在学校&#xff0c;他学习了汇编和C语言。毕业后&#xff0c;他加入了一家嵌入式企业&#xff0c;发现C语言因其可移植性、开发效率和可读性而更为通用和适用。事实证明&#xff0c;…

排序算法-----冒泡排序与选择排序

目录 前言: 冒泡排序 原理图 代码实现 分析总结 选择排序 原理图 代码实现 分析总结 前言: 今天我们就开始学习排序算法&#xff0c;排序算法也是数据结构与算法在重要组成部分之一&#xff0c;排序算法是最经典的算法知识。因为其实现代码短&#xff0c;应该广&#x…

【设计模式】桥接模式在开发中的应用

1. 概述 桥接模式是一个非常简单的设计模式&#xff0c;可能大家在开发的过程中已经使用到了这种模式而不自知。总的来说&#xff0c;桥接模式最大的作用就是解耦&#xff0c;所谓的解耦&#xff0c;就是通过转换代码的设计&#xff0c;减少类与类&#xff0c;模块与模块之间的…

监听器,过滤器,拦截器

参考博文 文章目录 作用三者区别启动顺序拦截器简要说明实现接口HandlerInterceptor自定义拦截器配置拦截器 过滤器简要说明在springboot 启动类添加该注解ServletComponentScan写个过滤器类&#xff0c;实现Filter接口 监听器简要说明如何使用自定义事件自定义过滤器接口调用…

图片怎么转换成pdf格式?几种方法轻松转换

图片怎么转换成pdf格式&#xff1f;将图片转换成PDF格式的主要原因是方便共享和存储。PDF格式可以在不同的设备和操作系统上轻松打开和查看&#xff0c;而且可以保持原始图片的质量和分辨率。如果你需要将一些图片转换成PDF格式&#xff0c;你可能会问&#xff0c;“该如何做呢…

12个最受欢迎的3D打印机械臂【开源|DIY|套件】

推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 机器人手臂的用途各不相同&#xff0c;但大多数都能够执行拾取和放置任务&#xff0c;而有些则配备用于 CNC 工作、激光雕刻&#xff0c;甚至 3D 打印。 机械臂具有广泛的应用和各个领域&#xff0c;从执行精密手术和进行工…

两行代码实现Redis消息队列,简单易用

Redis列表数据类型非常适合作为消息队列使用。将新的消息插入到列表尾部&#xff0c;然后从列表头部取出消息进行处理。该方案简单易用&#xff0c;并且支持多个消费者并行处理消息。 两行核心代码即可实现消息队列&#xff0c;如下&#xff1a; // 推送消息 redisTemplate.o…

Java中级编程大师班<第一篇:初识数据结构与算法-数组(2)>

数组&#xff08;Array&#xff09; 数组是计算机编程中最基本的数据结构之一。它是一个有序的元素集合&#xff0c;每个元素都可以通过索引进行访问。本文将详细介绍数组的特性、用法和注意事项。 数组的基本特性 数组具有以下基本特性&#xff1a; 有序性&#xff1a; 数…

初探词法分析实验

本次实验使用C对编译过程中的分词进行初步探究&#xff0c;以下是实验代码&#xff0c;输入文件需要在main函数中自己填写文本所在地址 #include <iostream> #include <stdlib.h> #include <stdio.h> #include<string> #define M 20 using namespace…

核心实验15_端口安全_ENSP

项目场景&#xff1a; 核心实验15_端口安全_ENSP 可指定该接口下最多接入几个设备&#xff08;通过mac绑定实现&#xff09;&#xff0c;人为增加设备时可设置接口自动down掉等&#xff0c;详见补充 实搭拓扑图&#xff1a; 具体操作&#xff1a; sw1: [Huawei]int g0/0/1 [H…

编辑视频无需第三方软件,在iPhone上也可以轻松编辑视频

如果你学会了如何在iPhone上编辑视频,你可以在很大程度上把匆忙拍摄的视频变成适合好莱坞的视频。好吧,也许这有点夸张了,但至少,你可以通过使用照片应用程序中的编辑工具,让你的视频看起来更令人印象深刻。 虽然它不一定能与最好的视频编辑软件相匹配,但它仍然非常适合…