WPF 点击按钮时更改按钮样式界面效果的 XAML 实现方法
在 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 实现方法的更多相关文章
- 使用 JavaScript 中的 document 对象查找 HTML 元素,实现“登录”按钮的高亮特效 鼠标悬浮于“登录”按钮时,按钮高亮显示;
查看本章节 查看作业目录 需求说明: 使用 JavaScript 中的 document 对象查找 HTML 元素,实现"登录"按钮的高亮特效 鼠标悬浮于"登录" ...
- Js制作点击输入框时默认文字消失的效果
(从已经死了一次又一次终于挂掉的百度空间人工抢救出来的,发表日期 2014-02-17) 为了提高用户体验和易用度,一些设计师会对网页中用户经常用的东西进行优化,比如输入框.一般的输入框是怎样优化的呢 ...
- WPF在在设计模式,使用动态样式
1.问题分析 WPF有时候要用到主题样式,比如颜色主题(红色.黄色之类的)通常是key相同,而value不同,比如会这么写: Background="{DynamicResource Bac ...
- 常见问题1:默认div隐藏,点击按钮时出现,再点击时隐藏。
例:默认div隐藏,点击按钮时出现,再点击时隐藏. <a href="#" onclick="f('ycbc')"; >控制按钮</a> ...
- WPF点击不同界面上的按钮实现界面切换
原文:WPF点击不同界面上的按钮实现界面切换 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_29844879/article/details/ ...
- 点击Cell中的按钮时,如何取所在的Cell
4.点击Cell中的按钮时,如何取所在的Cell:-(void)OnTouchBtnInCell:(UIButton *)Btu{CGPoint point = btn.center;point = ...
- WebView点击加载的页面中的按钮时不弹出新窗口以及在加载后执行javascript
mWebView.setWebViewClient(new WebViewClient() { //点击网页中按钮时,在原页面打开 public boolean shouldOverrideUrlLo ...
- [C# 基础知识系列]专题五:当点击按钮时触发Click事件背后发生的事情 (转载)
当我们在点击窗口中的Button控件VS会帮我们自动生成一些代码,我们只需要在Click方法中写一些自己的代码就可以实现触发Click事件后我们Click方法中代码就会执行,然而我一直有一个疑问的—— ...
- jqgrid 点击列头的超链接或按钮时,不触发列排序事件
接上篇文章:jqgrid 将列头设置为超链接或按钮 如果在列头设置了超链接或按钮,在点击超链接或按钮时会触发列的排序事件. 原由:点击超链接/按钮会触发排序的冒泡事件 解决方法:点击超链接/按钮时,阻 ...
- chrome 获得点击按钮时的事件
初次了解浏览器高级点的功能,原来这么强 想了解点击一个网页的按钮时触发了什么事件,firefox chrome确实很强大,基本可以监控所有内容 以chrome为例: 在按钮上 右键检查 或者 F12 ...
随机推荐
- TypeScript筑基笔记一:Visual Studio Code 创建Typescript文件和实时监控
问题一:电脑如何安装Typescript? 答案:打开电脑cmd 输入以下指令: npm install -g typescript 中国电脑因为访问慢,可以先安装cnpm后再安装 安装cnpm指令 ...
- Oracle 常用建库模板
记录一下 create tablespace lxw_tablespace datafile '/oradata/orcl/lxw_data_01.ora' size 30G; --或者 create ...
- KingbaseES V8R6 运维案例之---数据库连接访问故障分析
KingbaseES V8R6运维案例之---数据库连接访问故障分析 案例说明: 在部署KingbaseES V8R6后,正常启动数据库服务,但是通过ksql连接数据库服务访问时,出现连接到postg ...
- KingbaseES 原生XML系列五--XML关系表函数
KingbaseES 原生XML系列五--XML关系表函数(QUERY_TO_XML,TABLE_TO_XML,XMLTABLE) XML的简单使其易于在任何应用程序中读写数据,这使XML很快成为数据 ...
- scala入门输出helloworld
1 object HelloScala{ 2 def main(args : Array[String]){ 3 println("hello scala") 4 } 5 } He ...
- #博弈论,贪心#AT2376 [AGC014D] Black and White Tree
题目传送门 分析 考虑到先手放一个白点后手必将在相邻位置放一个黑点, 如果没有合适的位置放黑点先手必胜,也就是问是否存在完美匹配, 直接从叶子节点到根贪心匹配即可 代码 #include <cs ...
- 网站优化之robots.txt
本文于2015年底完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. 在查询favicon.ico相关的资料时,无间中看到了robots.tx ...
- 【直播回顾】OpenHarmony 3.1 Release版本南北向关键能力解读
OpenHarmony 3.1 Release版本发布后,广大开发者们纷纷开始上手体验新版本的功能.但随之而来的一系列问题,摆在了大家的面前:OpenHarmony 3.1这一版本,都有哪些重要的能力 ...
- 三步就能在OpenHarmony中实现车牌识别
介绍 本车牌识别项目是基于开源项目 EasyPR(Easy to do Plate Recognition)实现.EasyPR 是一个开源的中文车牌识别系统,基于 OpenCV 开源库开发. 本项目使 ...
- Kubernetes 的 NameSpace 无法删除应该怎么办?
概述 有时候我们操作不规范,或者删除的先后顺序有问题,或者某项关键服务没有启动,导致 Kubernetes 经常会出现无法删除 NameSpace 的情况.这种情况下我们应该怎么办? 规范删除流程 其 ...