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 ...
随机推荐
- 三维模型3DTile格式轻量化的跨平台兼容性问题分析
三维模型3DTile格式轻量化的跨平台兼容性问题分析 三维模型3DTile格式是一种开放的.高效的和互操作的空间信息数据格式.然而,它作为一种新兴的技术,其在轻量化与跨平台兼容性方面存在着一些问题. ...
- 记录--Event Loop事件循环、微任务、宏任务
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 JS是一门单线程语言,单线程就意味着,所有的任务需要排队,前一个任务结束,才会执行下一个任务.这样所导致的问题是:如果JS执行的时间 ...
- 记录--有关CSS盒模型之内边距、边框、外边距的十九问题
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 本篇文章主要探讨盒模型,以及内边距.边框.外边距的面试题与思考,也希望您能把您的思考和遇到的问题以评论的方式补充下,后期,我将会补充到文章 ...
- 利用Python 去重聚合Excel数据并对比两份数据的差异
问题背景 在数据处理过程中,常常需要将多个数据表进行合并,并进行比对,以便找出数据的差异和共同之处.本文将介绍如何使用 Pandas 库对两个 Excel 数据表进行合并与比对,并将结果输出到新的 E ...
- GPT-SoVITS教程,接入酒馆AI,SillyTavern-1.11.5,让AI女友声若幽兰
本次分享一下如何将GPT-SoVITS接入SillyTavern-1.11.5项目,让让AI女友声若幽兰,首先明确一下,SillyTavern-1.11.5只是一个前端项目,它没有任何大模型文本生成能 ...
- Linux系统上安装jdk(CentOS 7 )
目录 001. 搜索jdk安装包 002. 下载安装jdk1.8 003. 配置环境变量 004. 验证是否配置成功 001. 搜索jdk安装包 yum search java | grep jdk ...
- Scala 递归和尾递归
1 package com.atguigu.function 2 3 object Recursion { 4 def main(args: Array[String]): Unit = { 5 // ...
- 什么是OOP(Object Oriented Programming)面向对象编程
1.认识面向对象首先要认识面向过程 面向过程编程,举个例子 比如有一天你要吃回锅肉,你会先去准备食材,然后一步一步把这道菜做出来,这就是面向过程. 还有一种方式你依然可以得到这道菜,你可以去饭店直接点 ...
- 企业数据清洗项目实践day3
封装昨天的生成json方法,生成标准字段方法以及生成最终文件的方法. 1 import pandas as pd 2 import xlwt 3 """ 4 rank的一 ...
- Cesium 根据飞机航线计算飞机的Heading(偏航角)、Pitch(俯仰角)、Roll(翻滚角)
需求 设置飞机的一些坐标位置(经纬度高度),插值得到更多的坐标位置,然后飞机按照这些坐标集合形成的航线飞行,飞机的朝向.俯仰角以及飞机转弯时的翻转角根据坐标集合计算得出,而不需要手动设置heading ...