草庐IT

WPF开发快速入门【2】WPF的基本特性(Style、Trigger、Template)

Enjoy programming! 2023-03-28 原文

概述

本文描述几个WPF的常用特性,包括:样式、触发器和控件模板。

 

样式/Style

Style就是控件的外观,在XAML中,我们通过修改控件的属性值来设置它的样式,如:

 <!--直接定义style-->
 <Border Grid.Row="0" Grid.Column="0" Background="Pink"/>

 这样写的缺点是如果有一组控件具备同样的样式,代码不能复用,每个都要单独设置。所以,需要将样式代码提取出来,以便共用。

    <UserControl.Resources>
        <Style x:Key="Border1" TargetType="Border">
            <Setter Property="Background" Value="Orange"/>
        </Style>       
    </UserControl.Resources>

    <!--在文件头部定义-->
    <Border Grid.Row="0" Grid.Column="1" Style="{StaticResource Border1}"/>

 TargetType="Border"表示这个样式表是针对Border控件的,Border1是这个样式的名字,如果不设置Key,表示对该页面范围内的所有Border控件均有效。

上述这个样式是定义在该控件头部的,它的有效范围就是当前页面。如果有多个页面或窗体需要用到同样的样式,那就需要在App.xaml中进行定义。

实际应用时,我们一般不会直接在App.xaml中定义样式,而是会新建一个资源字典文件,在该资源文件中进行定义,然后在App.xaml中包含该文件即可。

资源文件的定义:Style/Colors.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">    
    <Style x:Key="Border2" TargetType="Border">
        <Setter Property="Background" Value="Chocolate"/>
    </Style>     
</ResourceDictionary>

 在App.xaml中包含该资源文件 

<Application x:Class="LearnWPF.App">
    <Application.Resources>
        <ResourceDictionary>
                <ResourceDictionary Source="Style/Colors.xaml"/>              
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

 我们还可以在类库中定义样式,定义方式同上,同时,仍需要在在App.xaml中包含该资源文件,但包含方式和本地的不一样。

<ResourceDictionary Source="pack://application:,,,/LearnWPF.Controls;component/Style/CommonColors.xaml"/>

 可以看出,这和我们引用第三方控件中的样式资源的方式是一样的。

  <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
  <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
  <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />

  

触发器/Triggger

在样式中应用触发器,是指在控件某个触发属性变化时,要执行的属性变化,或启动某个动画。

    <UserControl.Resources>
        <Style x:Key="MyButton" TargetType="Button">
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="FontWeight" Value="Normal"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="FontSize" Value="16"/>
                    <Setter Property="FontWeight" Value="Bold"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </UserControl.Resources>

 以上表示当IsMouseOver=True时,将修改该控件的FontSize和FontWeight属性。IsMouseOver=False时,控件属性将恢复原来的值。

 

控件模板/ControlTemplate

 有时候,我们需要完全修改控件的外观,这时就需要用到ControlTemplate,如下代码定义一个带指示灯的按钮

    <Window.Resources>
        <Style x:Key="myButton"  TargetType="Button">
            <Setter Property="Background" Value="SeaGreen"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border BorderThickness="1" BorderBrush="Gray" Background="{TemplateBinding Background}" CornerRadius="10" >
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left"  >
                                <Ellipse Width="20" Height="20" Fill="Green" Margin="10"/>
                                <TextBlock Text="{TemplateBinding Content}" VerticalAlignment="Center" Margin="2 0"/>
                            </StackPanel>
                        </Border>                       
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

 需要注意:这里有两个地方声明了TargetType="Button"。TemplateBinding 表示采用控件原来的值。在控件模板的定义中,也是可以使用Trigger的。

    <Window.Resources>
        <Style x:Key="myButton"  TargetType="Button">
            <Setter Property="Background" Value="Silver"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border BorderThickness="1" BorderBrush="Gray" Background="{TemplateBinding Background}" CornerRadius="10" >
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left"  >
                                <Ellipse x:Name="ell" Width="20" Height="20" Fill="LightGreen" Margin="10"/>
                                <TextBlock Text="{TemplateBinding Content}" VerticalAlignment="Center" Margin="2 0"/>
                            </StackPanel>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True"  >
                                <Setter TargetName="ell" Property="Fill" Value="Red"/>
                                <Setter Property="FontSize" Value="18"/>
                                <Setter Property="Foreground" Value="White"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

 与前文提到的Trigger不同,这里在设置属性时,多了一个TargetName="ell"

<Setter TargetName="ell" Property="Fill" Value="Red"/>

 这表示,该项操作是针对ell这个控件的。

如果没有指定TargetName,能设定的属性仅仅是包含Button这个控件所具备的属性,Button是没有Fill属性的,就算原始控件是包含Fill属性的,也不能保证该属性的设置能向下延伸到你想要修改的控件,所以在ControlTemplate中修改控件属性时应指定TargetName 。

 

资源

系列目录:WPF开发快速入门【0】前言与目录 

代码下载:Learn WPF: WPF学习笔记 (gitee.com)

有关WPF开发快速入门【2】WPF的基本特性(Style、Trigger、Template)的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  3. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  4. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  5. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  6. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  9. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  10. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

随机推荐