wpf中的样式与模板
1.WPF样式
类似于Web应用程序中的CSS,在WPF中可以为控件定义统一的样式(Style)。样式属于资源的一种,例如为Button定义统一的背景颜色和字体:
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="Yellow" />
</Style>
</Window.Resources>
<StackPanel>
<Button>Button A</Button>
</StackPanel>
在Style中定义的属性及值,影响到Window中的所有类型为Button的控件的样式
这种样式,类似于CSS中的类型选择器,为某种类型定义样式。
此外还可以在Style中加入x:Key属性,做为特定的样式(注意,这种也需要定义TargetType);
在第一个样式的基础上创建一个新样式可以达到这一目的,如下所示:<Window.Resources>
<Style x:Key="BigFontButtonStyle">
<Setter Property="Control.FontFamily" Value="Times New Roman" />
<Setter Property="Control.FontSize" Value="18" />
<Setter Property="Control.FontWeight" Value="Bold" />
</Style>
<Style x:Key="EmphasizedBigFontButtonStyle" BasedOn="{StaticResource BigFontButtonStyle}">
<Setter Property="Control.Foreground" Value="White" />
<Setter Property="Control.Background" Value="DarkBlue" />
</Style>
</Window.Resources>
以编程方式设置样式
若要以编程方式向元素分配命名样式,请从资源集合中获取该样式,然后将其分配给元素的 Style 属性。请注意,资源集合中的项是 Object 类型,因此,将检索到的样式分配给 Style 属性之前,必须将该样式强制转换为 Style。例如,若要对名为 textblock1 的 TextBlock 设置定义的 TitleText 样式,请执行以下操作:
textblock1.style=(style)Resources["TitleText"];
请注意,样式一旦应用,便会密封并且无法更改。如果要动态更改已应用的样式,必须创建一个新样式来替换现有样式。
2.wpf模板
当一个控件的外观不满足要求的时候,我们可以使用“控件模板”的方式更改控件的外观,WPF中的所有控件,只要有视觉外观,就会有Template property,且将此property的值设定为一个ControlTemplate对象。Button之所以看起来像Button就是因为受到了ControlTemplate对象的直接影响。ControlTemplate对象定义了控件的完整外观,且你可以替换此对象。
抽象的FrameworkTemplate类型只定义了三个property。只读的Boolean property用来标识此模板是否可以被修改。Resources property的类型是ResourceDictionary,让我们定义一些只能够在模板内部使用的资源。第三个property最重要,叫做visualTree,定义组成此控件外观的Element的layout。
ControlTemplate类型多加了两个property定义:TargetType用来指明,哪个类型的控件,适合应用到该模板;Triggers是Trigger对象的collection。
所有派生自ContentControl的类型都使用ContentPresenter类型的对象来显示它们的内容。ContentPresenter派生自FrameworkElement,你可以在模板的视觉树内包含一个ContentPresenter对象,用来盛放模板中要放置的内容。ContentPresenter element负责显示所有“派生自ContentControl”控件的内容。ContentPresenter将这个世界分成两类对象:UIElement的后代和非UIElement的后代,对于非UIElement的后代,ContentPresenter会调用对象的ToString方法,用文本来展示该对象。这个功能让“派生自ContentControl”的控件可以用来显示任何种类的内容。
<Window.Resources>
<Style TargetType="Button" x:Key="ButtonStyle">
<!--设置按钮的默认的样式-->
<Setter Property="FontFamily" Value="Comic Sans MS"/>
</Setter>
<!--设置按钮的模板-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"/>
<ContentPresenter
Margin="5"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Margin="5" Style="{StaticResource ButtonStyle}"
Width="100" Height="100"
Content="My Button">
</Button>
<Button Margin="5" Width="200">Common Button</Button>
</StackPanel>
WPF包含数据模板和控件模板
控件模板又包括ControlTemplate和ItemsPanelTemplate,这里讨论一下ControlTemplate。其实WPF的每一个控件都有一个默认的模板,该模板描述了控件的外观以及外观对外界刺激所做出的反应。我们可以自定义一个模板来替换掉控件的默认模板以便打造个性化的控件。与Style不同,Style只能改变控件的已有属性值(比如颜色字体)来定制控件,但控件模板可以改变控件的内部结构(VisualTree,视觉树)来完成更为复杂的定制,比如我们可以定制这样的按钮:在它的左办部分显示一个小图标而它的右半部分显示文本。要替换控件的模板,我们只需要声明一个ControlTemplate对象,并对该ControlTemplate对象做相应的配置,然后将该ControlTemplate对象赋值给控件的Template属性就可以了。ControlTemplate包含两个重要的属性:1,VisualTree,该模板的视觉树,其实我们就是使用这个属性来描述控件的外观的2,Triggers,触发器列表,里面包含一些触发器Trigger,我们可以定制这个触发器列表来使控件对外界的刺激发生反应,比如鼠标经过时文本变成粗体等。参考以下代码
<Button>
<Button.Template>
<ControlTemplate>
<!--定义视觉树-->
<Grid>
<Ellipse Name="faceEllipse" Width="{TemplateBinding Button.Width}"
Height="{TemplateBinding Control.Height}" Fill="{TemplateBinding Button.Background}"/>
<TextBlock Name="txtBlock" Margin="{TemplateBinding Button.Padding}" VerticalAlignment="Center" HorizontalAlignment="Center"
Text="{TemplateBinding Button.Content}" />
</Grid>
<!--定义视觉树_end-->
</ControlTemplate>
</Button.Template>
</Button>
在上面的代码中,我们修改了Button的Template属性,我们定义了一个ControlTemplate,在<ControlTemplate> ...</ControlTemplate>之间包含的是模板的视觉树,也就是如何显示控件的外观,我们这里使用了一个Ellipse(椭圆)和一个TextBlock(文本块)来定义控件的外观。很容易联想到一个问题:控件(Button)的一些属性,比如高度、宽度、文本等如何在新定义的外观中表现出来呢?我们使用TemplateBinding 将控件的属性与新外观中的元素的属性关联起来Width="{TemplateBinding Button.Width}" ,这样我们就使得椭圆的宽度与按钮的宽度绑定在一起而保持一致,同理我们使用Text="{TemplateBinding Button.Content}"将TextBlock的文本与按钮的Content属性绑定在一起。
wpf中的样式与模板的更多相关文章
- WPF中通过代码定义模板
WPF中可以再XAML中定义模板,也可以通过C#代码定义模板,通过代码可能更清楚的看清其逻辑,而且代码的好处就是可以随时动态的去操作,而在XAML中定义的一般都是静态的. //控件呈现的显示内容1(这 ...
- Wpf中鼠标样式的修改,作用点修改
最近,在做一个控件的鼠标样式,Ps加了插件,可以编辑生成.cur格式的图标. 可是,所有的改完以后,调试运行,结果发现自己制作的图标的作用点总是在左上角,而不是在"手形"图标的食指 ...
- WPF QuickStart系列之样式和模板(Style and Template)
在WPF桌面程序中,当我们想构建一个统一的UI表现时(在不同操作系统下,显示效果一致),此时我们就需要使用到WPF中的样式和模板技术.简单来说,如果我们需要简单的给一个Button设置宽,高,Marg ...
- [WPF系列]-数据邦定之DataTemplate 对 ItemsControl 进行样式和模板处理
引言 即使 ItemsControl 不是 DataTemplate 所用于的唯一控件类型,将 ItemsControl 绑定到集合仍然很常见. 在 DataTemplate 中有哪些内容一节中, ...
- [No000012F]WPF(7/7) - 样式,触发器和动画
WPF Tutorial : Beginning [^] WPF Tutorial : Layout-Panels-Containers & Layout Transformation [^] ...
- WPF学习之深入浅出话模板
图形用户界面应用程序较之控制台界面应用程序最大的好处就是界面友好.数据显示直观.CUI程序中数据只能以文本的形式线性显示,GUI程序则允许数据以文本.列表.图形等多种形式立体显示. 用户体验在GUI程 ...
- wpf 中的style
我们通常说的模板是用来参照的,同样在WPF中,模板是用来作为制作控件的参照. 一.认识模板 1.1WPF菜鸟看模板 前面的记录有提过,控件主要是算法和数据的载体.控件的算法主要体现在可以激发的事件.可 ...
- WPF中TreeView的使用
因为项目中需要用到TreeView控件,由于是第一次在WPF中用到,因此事先在网上搜了很多关于数据绑定的方法介绍,个人经过实际应用,觉得WPF中的HierarchicalDataTemplate定义模 ...
- WPF编程学习——样式
本文目录 1.引言 2.怎样使用样式? 3.内联样式 4.已命名样式 5.元素类型样式 6.编程控制样式 7.触发器 1.引言 样式(Style),主要是用来让元素或内容呈现一定外观的属性.WPF中的 ...
随机推荐
- Python图像处理库PIL从入门到精通
https://blog.csdn.net/column/details/pythonpil.html 示例: from PIL import Image import pytesseract pyt ...
- 关于postman使用上发现的一点问题
之前后台用的java,一直用的postman测试接口数据,之前不管是get.post.delete.put请求都是在param传递的数据,java下面是没问题可以测试的.但是今天自己写Node发现po ...
- 不支持模块化规范的插件可以使用import 导入的原因
模块化当中的模块其实是个闭包,然后导出这个闭包,这个是为了解决全局变量污染的问题的. 所以模块当中直接定义的变量 比如 var foo = 0; 这个并不会是全局变量,而是当前模块闭包当中的局部变量 ...
- 应用defineProperty简单实现vue的双向数据绑定
双向数据绑定简易版本如何应用defineProperty的getter setter 方法 有这样HTML片段 <input type="text" id="dem ...
- hdu4635 有向图最多添加多少边使图仍非强连通
思路:先缩点成有向无环图,则必然含有出度为0的点/入度为0的点,因为要使添加的边尽量多,最多最多也就n*(n-1)条减去原来的m条边,这样是一个强连通图,问题转化为最少去掉几条,使图不强连通,原来图中 ...
- VUE之命令行报错:Expected indentation of 4 spaces but found 6
使用vue时候,经常被一大片警告惊呆了,这是webpack默认的语法检查插件ESLint在做警告, [ESLint是一个语法规则和代码风格的检查工具,可以用来保证写出语法正确.风格统一的代码] 但是我 ...
- LibieOJ 6170 字母树 (Trie)
题目链接 字母树 (以每个点为根遍历,插入到trie中,统计答案即可)——SamZhang #include <bits/stdc++.h> using namespace std; #d ...
- cf744
Codeforces Round #385 (Div. 1) <br > A.Hongcow Builds A Nation 贪心. 显然就是凑成一个最大的块即可 那么首先并查集处理已经确 ...
- 浅析 JavaScript 中的闭包(-------------------------------------------)
一.前言 对于 JavaScript 来说,闭包是一个非常强大的特征.但对于刚开始接触的初学者来说它又似乎是特别高深的.今天我们一起来揭开闭包的神秘面纱.闭包这一块也有很多的文章介绍过了,今天我就浅谈 ...
- openfire Android学习(一)----实现用户注册、登录、修改密码和注销等
以前学习过用Scoket 建立聊天,简单的建立聊天是没问题的,但如果要实现多人复杂的聊天,后台服务器代码就比较复杂,对于我这新手来讲就比较难了.后来在网上看到用openfire做服务器,利用强大的Sm ...