8天入门wpf—— 第三天 样式

说起样式,大家第一反应肯定是css,好的,先上一段代码。

html{border:0;}
ul,form{margin:0; padding:0}
body,div,th,td,li,dd,span,p,a{font-size:12px; font-family:Verdana,Arial,"宋体";color:#575757;}
h3,input{font-size:12px; font-family:Verdana,Arial,"宋体";color:#4465a2;}

body {
 /*background-color:#eaeaea;*/
 /*e5e5e5*/
 /*BACKGROUND: url(../images/header_bg.jpg) #fff repeat-x;*/
 BACKGROUND: url(../images/color_1.png) #fff repeat-x 0px -233px;
 margin:0px;
 padding:0px;
}

ul{list-style:none;}
h1,h2,h4,h5,h6{ font-size:14px; color:#333;}
img{border:0;}
a {color:#333333;text-decoration:none;}
a:hover{color:#ff0000;text-decoration:underline;}

我们知道css实现了内容与样式的分离,既然wpf跟webform非常类似,那么肯定也有一套能够实现css的功能,是的。这就是wpf的style。

一:Style类

首先我们看看Style里面有哪些东西,在vs里面我们可以通过按F12查看类的定义。


下面我们一一解读下:

1:Setters

从上图我们知道Setters的类型是SetterBaseCollection,可以看得出是一个存放SetterBase的集合,SetterBase派生出了两个类

Setter和EventSetter,下面我们看看Setter类的定义。


这里我们看到了两个非常重要KV属性Property和Value,我们拿css找找对应关系。

html{border:0;}

html => Style.TargetType

border => Property

0 => Value

估计大家想迫不及待的试一试,好了,我先做一个简单的demo。

<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:sys="clr-namespace:System;assembly=mscorlib"
 Title="MainWindow" Height="350" Width="525">
 <Window.Resources>
 <Style TargetType="Button">
 <Setter Property="Background" Value="Pink"/>
 <Setter Property="FontSize" Value="22"/>
 </Style>
 </Window.Resources>
 <Grid>
 <Button Content="一线码农"/>
 </Grid>
</Window>

最后效果:


仔细看看,是不是找到了css的感觉,有人肯定要问,这不就是标签选择器吗?能不能做成“id选择器”,当然可以,我们只需要给style取一个名字,

然后在控件上引用一下就ok了。

<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:sys="clr-namespace:System;assembly=mscorlib"
 Title="MainWindow" Height="350" Width="525">
 <Window.Resources>
 <Style x:Key="mystyle" TargetType="Button">
 <Setter Property="Background" Value="Pink"/>
 <Setter Property="FontSize" Value="22"/>
 </Style>
 </Window.Resources>
 <Grid>
 <Button Style="{StaticResource ResourceKey=mystyle}" Content="一线码农"/>
 </Grid>
</Window>

现在我们添加一个label,如果我们也需要同样的“背景色”和“字体”,那么我们是否要重新写一个label的样式吗?答案肯定是否定的,聪明的你肯定会

想到”基类“。我们发现label和button都是继承自ContentControl,都属于内容控件,那么何不在TargetType中定义为ContentControl不就ok了吗?

<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:sys="clr-namespace:System;assembly=mscorlib"
 Title="MainWindow" Height="350" Width="525">
 <Window.Resources>
 <Style x:Key="mystyle" TargetType="ContentControl">
 <Setter Property="Background" Value="Pink"/>
 <Setter Property="FontSize" Value="22"/>
 </Style>
 </Window.Resources>
 <Grid>
 <Button Style="{StaticResource ResourceKey=mystyle}"
 Content="Button" Height="23" Margin="132,99,0,0" Name="button1" Width="75" />
 <Label Style="{StaticResource ResourceKey=mystyle}"
 Content="Label" Height="28" Margin="140,168,0,0" Name="label1" />
 </Grid>
</Window>


2:TargetType

我们在说Setter的时候也提到了,其实TargetType也就是将样式施加到某一个对象上,具体的也没什么好说的。

3:BaseOn

我们知道css具有“继承和覆盖”的特性,同样我们的wpf中也是具有的。

<1>:继承

<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:sys="clr-namespace:System;assembly=mscorlib"
 Title="MainWindow" Height="350" Width="525">
 <Window.Resources>
 <Style x:Key="baseStyle" TargetType="Button">
 <Setter Property="FontSize" Value="22"/>
 </Style>
 <Style x:Key="childStyle" TargetType="Button"
 BasedOn="{StaticResource ResourceKey=baseStyle}">
 <Setter Property="Background" Value="Pink"/>
 </Style>
 </Window.Resources>
 <Grid>
 <Button Style="{StaticResource ResourceKey=childStyle}" Content="一线码农"/>
 </Grid>
</Window>

效果:


从上例中,我们看到childStyle继承到了baseStyle中的fontSize,最终的效果也是我们期望看到的。

<2>:覆盖

我们知道css遵循“就近原则”。

①:“行内”覆盖“嵌入”,“嵌入”覆盖“外部”


我们可以清楚的看到,行内样式覆盖了嵌入样式。

②:同级别遵循“就近”。


从button的颜色上看,我们可以获知Pink已经被BurlyWood覆盖。

4:Triggers

顾名思义,是触发器的意思,我们可以认为是wpf在style中注入了一些很简单,很sb的js代码。

wpf中有5种trigger,都是继承自TriggerBase类。

<1> Trigger,MuliTrigger

我们知道js是事件驱动机制的,比如触发mouseover,mouseout,click等事件来满足我们要处理的逻辑,那么wpf在不用写C#代码的情况下

用trigger就能够简单的满足这些事件处理。

下面举个例子

<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:sys="clr-namespace:System;assembly=mscorlib"
 Title="MainWindow" Height="350" Width="525">
 <Window.Resources>
 <Style x:Key="childStyle" TargetType="Button">
 <Setter Property="Background" Value="BurlyWood"/>
 <Style.Triggers>
 <!-- 当IsMouseOver的时候,Button颜色变成粉色 -->
 <Trigger Property="IsMouseOver" Value="True">
 <Setter Property="Background" Value="Pink"/>
 </Trigger>
 </Style.Triggers>
 </Style>
 </Window.Resources>
 <Grid>
 <Button Style="{StaticResource ResourceKey=childStyle}" Content="一线码农">
 </Button>
 </Grid>
</Window>

最后的效果就是当isMouseOver=true的情况下,button的Background变成Pink。

然而trigger只能满足在单一的条件下触发,那么我想在多个条件同时满足的情况下才能触发有没有办法做到呢?刚好MuliTrigger就可以帮你实现。

<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:sys="clr-namespace:System;assembly=mscorlib"
 Title="MainWindow" Height="350" Width="525">
 <Window.Resources>
 <Style x:Key="childStyle" TargetType="Button">
 <Setter Property="Background" Value="BurlyWood"/>
 <Style.Triggers>
 <MultiTrigger>
 <MultiTrigger.Conditions>
 <Condition Property="IsMouseOver" Value="True"></Condition>
 <Condition Property="IsPressed" Value="True"></Condition>
 </MultiTrigger.Conditions>
 <Setter Property="Background" Value="Pink"/>
 </MultiTrigger>
 </Style.Triggers>
 </Style>
 </Window.Resources>
 <Grid>
 <Button Style="{StaticResource ResourceKey=childStyle}" Content="一线码农">
 </Button>
 </Grid>
</Window>

这里我们看到,只有满足了ismouseover和ispressed的时候,我们的button才会变成粉色。

<2>DataTrigger,MultiDataTrigger

这个跟上面的Trigger有什么不同呢?其实也就是DataTrigger多了一个Binding的属性,当然它的实际应用也是最广泛的。

<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:sys="clr-namespace:System;assembly=mscorlib"
 Title="MainWindow" Height="350" Width="525">
 <Window.Resources>
 <Style x:Key="childStyle" TargetType="Control">
 <Setter Property="Background" Value="BurlyWood"/>
 <Style.Triggers>
 <!-- 绑定当前的radio单选框,如果按钮选中,触发字体设置 -->
 <DataTrigger Binding="{Binding ElementName=radio, Path=IsChecked}" Value="True">
 <Setter Property="FontSize" Value="20"/>
 </DataTrigger>
 </Style.Triggers>
 </Style>
 </Window.Resources>
 <Grid>
 <RadioButton Style="{StaticResource ResourceKey=childStyle}"
 Name="radio" Content="我要变成20号字"></RadioButton>
 </Grid>
</Window>

效果:

=>

当我们选中radio的时候,字体变大,同样MultiDataTrigger这个多条件的使用道理也是一样的,这里就不介绍了。

<3>EventTrigger

这个trigger与动画有关,目前项目中还没接触到,留给大家自己研究研究。

5:IsSealed

用于标记style是只读的,类似我们在C#中的Seal关键字,来达到不允许让继承类使用,wpf使用seal常常在C#代码里面控制,在xaml中我们

是找不到的,有兴趣的话,大家自己研究研究。

时间: 2025-01-01 12:00:52

8天入门wpf—— 第三天 样式的相关文章

WPF 在开发机上样式显示正常,换到其它电脑上,所有样式都没有了

问题描述 如题WPF在开发机上样式显示正常,换到其它电脑上,所有样式都没有了,是不是资源字典没加载上去? 解决方案 解决方案二:程序集打包的时候要把东西都放上去,路径设置看看.路径错误或者就是没有放到程序集里面去解决方案三:资源字典是xaml文件,应该是自动生成进去的啊解决方案四:就是资源字典没加载成功解决方案五:引用3楼mjp1234airen4385的回复: 就是资源字典没加载成功 怎么解决?谢谢了急用解决方案六:<ResourceDictionary><ResourceDictio

MySQL入门学习(三)

mysql MySQL入门学习(三) --学习篇   了解了一些最基本的操作命令后,我们再来学习如何创建一个数据库和数据库表. 1.使用SHOW语句找出在服务器上当前存在什么数据库: mysql> SHOW DATABASES; +----------+ | Database | +----------+ | mysql  | | test   | +----------+ 3 rows in set (0.00 sec) 2.创建一个数据库abccs mysql> CREATE DATABA

分布式计算开源框架Hadoop入门实践(三)

Hadoop基本流程 计算开源框架Hadoop入门实践(三)-hadoop分布式计算框架"> 一个图片太大了,只好分割成为两部分.根据流程图来说一下具体一个任务执行的情况. 在分布式环境中客户端创建任务并提交. InputFormat做Map前的预处理,主要负责以下工作: 验证输入的格式是否符合JobConfig的输入定义,这个在实现Map和构建Conf的时候就会知道,不定义可以是Writable的任意子类. 将input的文件切分为逻辑上的输入InputSplit,其实这就是在上面提到的

Mesosphere入门指南--第三部分

本文讲的是Mesosphere入门指南--第三部分,[编者的话]本文为Mesosphere官方博客中发布的系列文章的第二部分,Mesosphere在本篇系列文章中分享了DC/OS的入门指南,并且做了演示. 在这系列之前的两篇文章中,我们通过配置DC/OS,安装和启动一个Docker应用程序并且安装了一些公有的负载均衡的基础设施.说真的,这些都是你需要开始的基本知识. 但是DC/OS有一堆很棒的特性,应用和扩展.在先进的4层Minuteman负载均衡之间,SQL和NoSQL例如Crate和Aran

WPF案例 (三) 模拟QQ“快速换装&quot;界面

原文:WPF案例 (三) 模拟QQ"快速换装"界面    这个小程序使用Wpf模拟QQ快速换装页面的动画特效,通过使用组合快捷键Ctrl+Left或Ctrl+Right,可实现Image平滑的向左或者向右滑动,页面如下,有兴趣的朋友可以下载源码         在构建这个示例的3D场景时,使用了ModelVisual3D和Model3DGroup元素,ModelVisual3D是一个3D容器类,用来包含3D元素,在这里使用Model3DGroup打包了3个GeometryModel3D

Manifest.xml 入门基础 (三) &amp;lt;uses-sdk&amp;gt;标签

Manifest.xml 入门基础 (三) <uses-sdk>标签 <uses-sdk android:minSdkVersion="integer" android:targetSdkVersion="integer" android:maxSdkVersion="integer" /> 用于表明应用程序与一个或多个版本 Android 平台的兼容性,以整数型的 API 级别来表示. 应用程序声明的 API 级别将与给

Docker入门教程(三)Dockerfile

本文讲的是Docker入门教程(三)Dockerfile,[编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第三篇,介绍了Dockerfile的语法,DockerOne目前在代码高亮部分还有些Bug,我们会尽快修复,目前在代码部分有会些字符会被转义. 在Docker系列教程的上一篇文章中,我们介绍了15个Docker命令,你应该对Docker有个大致的了解了.那15个命令在手动创建镜像时会用到,它们涵盖了镜像的创建.提交.搜索.pull和push的功能

深入XSLT第三章 --- 样式表结构

深入XSLT第三章 --- 样式表结构 在XML文件中样式表用元素xsl:stylesheet来表示. XSL处理器处理源文件和样式表时都必须采用XML的名域(Namespace)机制[W3C XML Names].所有XSL定义的元素(在文件中带有前缀xsl)只有是属于URI为http://www.w3.org/TR/WD-xsl中的某一个名域时才会被XSL识别; XSL 定义的元素只是在样式表中才认得,而并不是在源文件中.  xsl:stylesheet元素有一项可选的属性result-ns

ajax入门指南(三)

ajax入门指南,相信对ajax初学者会有所帮助. AJAX的主流框架:       浏览器端框架:       一.Prototype系列:         1.Prototype:http://prototype.conio.net,如果在Web应用中实现对Ajax的支持或者需要扩展一些基本的功能,Prototype是个很好的选择:         2.script.aculo.us:http://script.aculo.us,如果要在Web应用中实现更加在丰富的动态效果,提升用户体验,可