取消网站备案流程,wordpress发布文章关键词,网站主题类型,网站优点缺点文章目录 一、前言二、控件三、模板3.1 DataTemplate3.2 ControlTemplate3.3 ContentPresenter 四、结语 一、前言
最近又翻看了下刘铁猛的《深入浅出WPF》#xff0c;发现对模板章节中的部分内容有了更深的体会#xff0c;所以写篇文扯扯。
文章标题是Control与Template发现对模板章节中的部分内容有了更深的体会所以写篇文扯扯。
文章标题是Control与Template翻译成控件与模板。 将两者放一起不是无缘无故的在WPF中两者关系相当密切。 二、控件
如果有人问你什么是控件你会怎么回答 像界面上的按钮、文本框、滚动条啊都是控件。 所以控件可以理解为界面的组成元素。
以上是我之前的回答这样的回答没啥问题很直观很多人听了都能明白虽然可能不太严谨。
不过如果继续问 那为什么叫控件而不是其它名称。这种界面上的可交互的图案称作图形元素不是更直观、更贴切
我可能会回答控件这个名称是根据Control这个单词翻译过来的所以叫控件。
对面可能继续问那为什么英文叫Control而不是Graphic Element。 此时我陷入了沉思确实为什么会用Control这个单词来命名呢。
如何消除这个疑惑最简单的就是百度 百度词条 控件是指对数据和方法的封装。 控件可以有自己的属性和方法其中属性是控件数据的简单访问者方法则是控件的一些简单而可见的功能、控件创建过程包含设计、开发、调试工作然后是控件的使用。 先别管百度说的是对是错但显然并不直观。你跟非程序员这么解释他可能还是不懂。
那么从专业的角度来看这段对控件的描述有没有道理呢。 学过程序的都知道程序的本质是数据结构与算法。
界面上的控件呈现了一定内容并且提供了一些交互方式用户通过交互可以改变程序状态。
那么控件呈现的内容本质是什么 是数据。 控件提供的交互方式本质/目的是什么 我想应该是程序逻辑比如你按下按钮最终程序内部会执行一个方法一段代码即程序逻辑程序状态可能会因此发生一些改变。
所以控件既是数据的表现形式以让用户可以直观地看到数据又是算法的表现形式以让用户方便地操作逻辑。
作为“表现形式”每个控件都是为了实现某种用户操作算法和直观显示某种数据而生的一个控件看上去是什么样子由它的“算法内容”和“数据内容”决定这也是哲学中常说的内容决定形式。
这样看来百度的这段话还是挺有道理的更接近控件的本质。 三、模板
接下来回到WPF中的模板。
在以往的GUI技术中控件内部的逻辑和数据是固定的程序员不能改变比如WinForms/QtQWidget对于控件的外观程序员能做的改变也非常有限一般就是设置控件的属性想改变控件的内部结构更是不可能。如果想扩展一个控件的功能或更改其外观让其更适合业务逻辑哪怕只有一丁点改变也经常要创建控件的子类或创建用户控件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主要由两大用处 通过更换ControlTemplate改变控件外观使之具有更优的用户体验及外观。接触ControlTemplate程序员与设计师可以并行工作程序员可以先用WPF标准控件进行编程等设计师工作完成后只需把新的ControlTemplate应用到程序中就可以了。 不过考虑到国内WPF开发的现状应该很少有设计师和程序员工作完全分离的。所以ControlTemplate的使用上也集中在第一点了。
但第一点听起来似乎和之前所说的冲突了ControlTemplate不是呈现算法的吗怎么变成改变控件外观的了。
其实这并不矛盾因为控件的外观和控件的本质息息相关。
Button为什么形状都差不多一般就是一个椭圆或矩形可点击点击后会凹下去。TextBox为什么都是一个矩形框里面可输入文字。ScrollBar为什么都是一个长条你可以拖动它移动。
还记得算法是什么吗 每本编程入门书都会说算法是解决问题的办法。
这些控件之所以有这样的外观和交互方式并不是凭空产生的而是人设计出来的。显然这样的设计就是为了解决一类问题即它是一种算法。
当你对控件效果不满意时就可能需要更改其外观以贴合实际需求。
此时我对ControlTemplate又有了一层理解。控件模板描述的是控件外观以及外观对外界刺激所做出的反应比如各种事件/按钮鼠标触摸后的背景色变化等而外观和对刺激的反应更深层的含义是该类控件要解决的问题的解决方案。
下面是一个实际开发中的ControlTemplate应用场景我需要在鼠标移动到按钮上时按钮的背景色发生变红色这是为了使鼠标移动到按钮的操作有反馈感
Style TargetTypeButtonStyle.TriggersTrigger PropertyIsMouseOver ValueTrueSetter PropertyTemplateSetter.ValueControlTemplate TargetTypeButtonBorder BackgroundredContentPresenter VerticalAlignmentCenter HorizontalAlignmentCenter//Border/ControlTemplate/Setter.Value/Setter/Trigger/Style.Triggers
/Style如代码所示用触发器检验鼠标是否在控件上若是则修改其控件模板主要就是将控件模板外的border的背景色变红。
3.3 ContentPresenter
实际上Button的结构就是这么简单
BorderContentPresenter/
/Border一个边框加一个ContentPresenter就组成了一个按钮。 那么ContentPresenter是什么 我们可以通过反编译看到其中结构下面是我整理出来的一个类关系图 你会发现ContentPresenter的结构和ContentControl高度重合。 这边我也不卖关子也不想花太多篇幅去深究它们的关系。 你可以把ContentPresenter直接理解成控件的数据内容模板DataTemplate。
有的控件继承了ContentControl我称之为内容控件。 也有部分控件没有继承它比如TextBox
也因此TextBox的默认控件模板中不存在ContentPresenter。这也很好理解都没有数据内容何来数据内容呈现
你可能会问那它的Text属性不是数据内容 当然是但从控件的角度来看Text这样的属性已经是相当基础了就是一段字串有点类似于“原子数据”而内容控件的Content可能是有分割必要的比如Button中可能会有文字描述/图标等。因此我个人倾向于Text本身这种简单的特性导致了它不作为内容模板出现。 四、结语
写了这么多主要就是谈了谈对控件以及两个模板的理解。 这种理解更像是WPF开发也不限于WPF的内功不对写代码直接产生效率提升但会有长远的积极影响。