在 WPF 中按钮 Button 将会吃掉路由事件,此时的 EventTrigger 如果通过 RoutedEvent 是 MouseLeftButtonDown 那么将会拿不到路由事件,也就触发不了,因此样式将不会变更。简单的解决方法就是通过 VisualStateManager 配合 VisualState 来实现

实现效果如下,所有代码都是 XAML 代码

实现方式为给 Button 定义一个样式,通过如下代码可以定义

<Style TargetType="Button">
</Style>

上面代码没有定义样式资源的 key 因此会对容器内所有的 Button 按钮样式生效,因此我将这个样式放在需要使用的容器里面,这样才不会干扰其他容器内的元素

<StackPanel>
<StackPanel.Resources>
<Style TargetType="Button"></Style>
</StackPanel.Resources>
</StackPanel>

接着新建一个按钮,如下代码

<StackPanel>
<StackPanel.Resources>
<Style TargetType="Button"></Style>
</StackPanel.Resources>
<Button Margin="10,10,10,10" Width="100" Height="100" Content="Button 1" HorizontalAlignment="Center"
VerticalAlignment="Center" />
</StackPanel>

接下来就是核心逻辑了,通过重写 Button 的 Template 内容,给内容的 Border 添加一些必要样式

<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border">
<Border.RenderTransform>
<ScaleTransform />
</Border.RenderTransform>
<Grid>
<Rectangle Fill="Blue"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

接着在 Border 添加 VisualStateManager 如下面代码

<Border x:Name="Border">
<Border.RenderTransform>
<ScaleTransform />
</Border.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Rectangle Fill="Blue"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>

可以看到上面代码有两个 VisualState 分别是 Normal 和 Pressed 两个,其中 Pressed 表示的是鼠标按下,因此可以通过在 Pressed 添加动画实现更改样式

<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
To="0.5" />
<DoubleAnimation Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
To="0.5" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>

如上面代码是更改缩放

那么抬起呢?其实抬起就是非 Pressed 也就是 Normal 状态,啥都不写将会自动还原为属性的值。原理是在依赖属性里面,其实属性是一个属性列表,将会取优先级最高的一个,而优先级是这样排序的

属性系统强制

活动动画或具有 Hold 行为的动画

本地值

TemplatedParent 模板属性

隐式样式

样式触发器

模板触发器

样式资源库

默认(主题)样式

继承

来自依赖属性元数据的默认值

详细请看 依赖项属性值优先级

所有代码如下

        <StackPanel>
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border">
<Border.RenderTransform>
<ScaleTransform />
</Border.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
To="0.5" />
<DoubleAnimation
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
To="0.5" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups> <Grid>
<Rectangle Fill="Blue"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources> <Button Margin="10,10,10,10" Width="100" Height="100" Content="Button 1" HorizontalAlignment="Center"
VerticalAlignment="Center" />
</StackPanel>

代码放在 github 欢迎小伙伴访问

当然,本文有很多知识点没有聊到,包括 Style 是什么,以及属性的配置应该如何写,还有动画 DoubleAnimation 是什么等等。我特别推荐小伙伴入门的时候看 微软技术教程 - 哔哩哔哩 ( ゜- ゜)つロ 乾杯~ Bilibili 的免费教程视频,包含了这些细节

WPF 点击按钮时更改按钮样式界面效果的 XAML 实现方法的更多相关文章

  1. 使用 JavaScript 中的 document 对象查找 HTML 元素,实现“登录”按钮的高亮特效 鼠标悬浮于“登录”按钮时,按钮高亮显示;

    查看本章节 查看作业目录 需求说明: 使用 JavaScript 中的 document 对象查找 HTML 元素,实现"登录"按钮的高亮特效 鼠标悬浮于"登录" ...

  2. Js制作点击输入框时默认文字消失的效果

    (从已经死了一次又一次终于挂掉的百度空间人工抢救出来的,发表日期 2014-02-17) 为了提高用户体验和易用度,一些设计师会对网页中用户经常用的东西进行优化,比如输入框.一般的输入框是怎样优化的呢 ...

  3. WPF在在设计模式,使用动态样式

    1.问题分析 WPF有时候要用到主题样式,比如颜色主题(红色.黄色之类的)通常是key相同,而value不同,比如会这么写: Background="{DynamicResource Bac ...

  4. 常见问题1:默认div隐藏,点击按钮时出现,再点击时隐藏。

    例:默认div隐藏,点击按钮时出现,再点击时隐藏. <a href="#" onclick="f('ycbc')"; >控制按钮</a> ...

  5. WPF点击不同界面上的按钮实现界面切换

    原文:WPF点击不同界面上的按钮实现界面切换 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_29844879/article/details/ ...

  6. 点击Cell中的按钮时,如何取所在的Cell

    4.点击Cell中的按钮时,如何取所在的Cell:-(void)OnTouchBtnInCell:(UIButton *)Btu{CGPoint point = btn.center;point = ...

  7. WebView点击加载的页面中的按钮时不弹出新窗口以及在加载后执行javascript

    mWebView.setWebViewClient(new WebViewClient() { //点击网页中按钮时,在原页面打开 public boolean shouldOverrideUrlLo ...

  8. [C# 基础知识系列]专题五:当点击按钮时触发Click事件背后发生的事情 (转载)

    当我们在点击窗口中的Button控件VS会帮我们自动生成一些代码,我们只需要在Click方法中写一些自己的代码就可以实现触发Click事件后我们Click方法中代码就会执行,然而我一直有一个疑问的—— ...

  9. jqgrid 点击列头的超链接或按钮时,不触发列排序事件

    接上篇文章:jqgrid 将列头设置为超链接或按钮 如果在列头设置了超链接或按钮,在点击超链接或按钮时会触发列的排序事件. 原由:点击超链接/按钮会触发排序的冒泡事件 解决方法:点击超链接/按钮时,阻 ...

  10. chrome 获得点击按钮时的事件

    初次了解浏览器高级点的功能,原来这么强 想了解点击一个网页的按钮时触发了什么事件,firefox chrome确实很强大,基本可以监控所有内容 以chrome为例: 在按钮上 右键检查 或者 F12  ...

随机推荐

  1. 记录--前端使用a链接下载内容增加loading效果

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 问题描述:最近工作中出现一个需求,纯前端下载 Excel 数据,并且有的下载内容很多,这时需要给下载增加一个 loading 效果. 代码 ...

  2. Arch Linux 安装手记

    背景 今天尝试安装龙芯版 Linux,本来希望能安装 Debian 版,但只找到一些文档,没找到可安装版的 ISO. 后来顺着这篇文章找到了Arch Linux,就尝试安装了一下. 安装后发现竟然不会 ...

  3. RepPointsV2:更多的监督任务,更强的性能 | NIPS 2020

    RepPointsV2的整体思想类似与Mask R-CNN,加入更多的任务来监督目标检测算法的学习.虽然在创新性上可能不够新颖,但论文的通用性还是很不错的,而且将角点任务的输出用于联合推理,从对比实验 ...

  4. KingbaseES V8R6 sslinfo 插件

    前言 KingbaseES对使用SSL 连接加密客户端/服务器通讯的本地支持,可以增加数据传输安全性. 本文展示配置ssl连接,并通过安装一个插件验证ssl加密认证使用. 一.配置ssl连接过程: s ...

  5. 学习Python前要了解的tips

    学习Python前要了解的tips 对后续的学习来说很重要,否则后续会出现一些奇奇怪怪的问题,而且很难找到解决方法.嘿嘿,就不要问我怎么知道的了吧,好多都是我踩过的坑 卸载电脑内软件 之前我一直用电脑 ...

  6. 【已解决】git push send-pack: unexpected disconnect while reading sideband packet

    解决办法:修改缓存大小 打开项目所在路径下的git目录 找到config文件,用记事本打开编辑. 添加如下内容并保存即可 [http] postBuffer = 1048576000

  7. #二分图匹配#UVA1194 Machine Schedule

    题目 有两台机器 \(A,B\) 分别有 \(n,m\) 种模式. 现在有 \(k\) 个任务.对于每个任务 \(i\) ,给定两个整数 \(a_i\) 和 \(b_i\)​, 表示如果该任务在 \( ...

  8. SQLAlchemy详解

    一.SQLAlchemy介绍 SQLAlchemy 是 Python SQL 工具包和对象关系映射器,为应用程序开发人员提供 SQL 的全部功能和灵活性. SQLAlchemy支持SQLite.Pos ...

  9. 基于ArkUI框架开发-ImageKnife渲染层重构

      ImageKnife是一款图像加载缓存库,主要功能特性如下: ●支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存. ●支持磁盘缓存,对于下载图片会保存一份至磁盘当中. ●支持进行图片 ...

  10. 重新点亮linux 命令树————文件权限和目录权限[九]

    前言 简单整理一下文件权限和目录权限. 正文 当打开ls -al的时候会出现相关的权限信息. 那么上面文件类型包括: 普通文件 d 目录文件 b 块特殊文件 (设备,比如u盘) c 字符特殊文件 (终 ...