不修改模板的前提下修改VisualState中的某些值
原文链接:不修改模板的前提下修改VisualState中的某些值 - 超威蓝火
UWP里有一件非常令人不爽的事,大部分控件只提供了Normal状态下的Background,Foreground,BorderBrush,而控件一般至少具有Normal、PointerOver、Pressed、Disabled,ItemContainerStyle还有Selected、PointerOverSelected、PressedSelected这几种。那么常规方法怎么修改这几个状态内的值呢?
当然是贴一遍又臭又长的Style。
那如果有很多不是很一样的控件,除了修改模板或者自定义一个控件之外,有没有办法修改状态内的值呢?
答案是肯定的。我们可以通过某些方法拿到VisualStateGroup对象,然后操作里面的Storyboard。
首先我们需要一个获取VisualStateGroup的方法,这玩意儿藏在Style中的Template中的第一个子元素里,而这个子元素会在需要的元素ApplyTemplate后,通过当猴子(爬树)得到:
public static Task<VisualStateGroup> GetCommonStates(this FrameworkElement element)
{
var vGroup = VisualStateManager.GetVisualStateGroups(element)?.FirstOrDefault(x => x.Name == "CommonStates");
var resultSource = new TaskCompletionSource<VisualStateGroup>();
if (vGroup == null)
{
if (element.GetFirstChild() is FrameworkElement ele)
{
element = ele;
vGroup = VisualStateManager.GetVisualStateGroups(element)?.FirstOrDefault(x => x.Name == "CommonStates");
}
else if (!element.IsLoaded())
{
void Element_Loaded(object sender, RoutedEventArgs e)
{
element.Loaded -= Element_Loaded;
vGroup = VisualStateManager.GetVisualStateGroups(element)?.FirstOrDefault(x => x.Name == "CommonStates");
if (vGroup == null)
{
if (element.GetFirstChild() is FrameworkElement ele2)
{
element = ele2;
vGroup = VisualStateManager.GetVisualStateGroups(element)?.FirstOrDefault(x => x.Name == "CommonStates");
}
}
resultSource.SetResult(vGroup);
}
element.Loaded += Element_Loaded;
}
else
{
return null;
}
}
else
{
resultSource.SetResult(vGroup);
}
return resultSource.Task;
}
这是一个老问题,在设置附加属性的时候,元素可能并没有加载完,这时候是没有第一个子元素的,所以要用一个内部方法或者内部的RouteEventHandler挂到Loaded上去获取。内部是因为要共享变量,而且要在进入Loaded事件之后卸载掉这个方法。
接下来我们要从CommonStates中获取Pressed和PointerOver这两个State:
var commonStates = await ele.GetCommonStates();
if (commonStates != null)
{
var storyboard = commonStates.States.FirstOrDefault(x => x.Name == "PointerOver")?.Storyboard;
if (storyboard != null)
{
var list = storyboard.Children.Where(x => BackgroundNames.Contains(Storyboard.GetTargetName(x).ToLowerInvariant()) && Storyboard.GetTargetProperty(x) == "Background");
foreach (var item in list)
{
item.SetAnimationValue(a.NewValue);
}
}
}
这样就大功告成了。
使用方法如下:
xmlns:helper="using:PointerStateHelper.Helpers"
<Button HorizontalAlignment="Center" VerticalAlignment="Center"
helper:PointerOverHelper.Background="Red" helper:PointerOverHelper.Foreground="Blue" helper:PointerOverHelper.BorderBrush="Transparent"
helper:PressedHelper.Background="Green" helper:PressedHelper.Foreground="Gray" helper:PressedHelper.BorderBrush="Transparent"
Content="哈哈哈" Padding="20,10" />
github:https://github.com/cnbluefire/PointerStateHelper
不修改模板的前提下修改VisualState中的某些值的更多相关文章
- 保留键的情况下取字典中最大的值(max\zip函数的联合使用)
在我们平常想要获取字典中value最大或者最小的值的时候,常常使用如下函数: testDict = {"age1":18,"age2":20,"age ...
- MVC下 把数据库中的byte[]值保存成图片,并显示在view页面
MVC下 把数据库中的byte[]值转成图片,并显示在view页面 controller中的action方法 //显示图片[AllowAnonymous]public ActionResult Sho ...
- 利用js取到下拉框中选择的值
现在的需求是:下拉框中要是选择加盟商让其继续选择学校,要是选择平台管理员则不需要选择学校.隐藏选择下拉列表. 选择枚举值: /// <summary> /// 平台角色 /// </ ...
- 【修改密码】Linux下修改Mysql的用户(root)的密码
修改的用户都以root为列.一.拥有原来的myql的root的密码: 方法一:在mysql系统外,使用mysqladmin# mysqladmin -u root -p password " ...
- 在无修改权限的情况下修改文件hosts中的内容
今天遇到了一个问题,本来希望修改hosts中的内容,但保存时被告知无权限,网上搜索有很多方法都无效,最后搜到一个简单的方法:将hosts文件复制到桌面上,修改,然后覆盖原来位置的hosts文件即可!
- 如何在某些情况下禁止提交Select下拉框中的默认值或者第一个值(默认选中的就是第一个值啦……)
群里有个帅哥问了这么个问题,他的下拉框刚进页面时是隐藏起来的,但是是有值的,为啥呢?因为下拉框默认选中了第一个值呗,,, 所以提交数据的时候就尴尬啦,明明没有选,但是还是有值滴.怎么办呢? 一开始看到 ...
- js下读取input中的value值
很多人(包括我),总想像以前操作js一样,读取到input中的值:document.getElementById('').value; 结果事实证明这样读到得是null. eval(document. ...
- jquery获取下拉框中的循环值
<select class="test" id="projectno" name="projectno"> <option ...
- JavaScript获取select下拉框中的第一个值
JavaScript获取select下拉框中的第一个值 1.说明 获取select下拉框中的第一个值 2.实现源码 <!DOCTYPE html PUBLIC "-//W3C//DTD ...
随机推荐
- ligbox 插件介绍
浏览器支持情况:一般情况都支持.最好是jQuery v1.x + lightbox.js,这样的组合IE6,IE7,IE8也支持! 1 light插件的下载地址:https://pan.baidu.c ...
- mysql 按出现次数排序
SELECT * FROM table a LEFT JOIN (SELECT key,count(*) as c FROM table GROUP BY key ) b on a.key=b.k ...
- (vue.js)element ui 表单重置
el-form需要接收一个model,并且需要配合el-form-item一起使用,并且在el-form-item上绑定prop属性,resetField方法才能好使. <el-form :mo ...
- 相机标定——OpenCV-Python Tutorials
原文地址http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_calib3d/py_calibration/py ...
- jstl标准标签库 常用标签
JSTL(JSP Standard Tag Library)标准标签库: 1, 核心标签(最常用, 最重要的) 表达式控制标签 out 输出常量 value---直接赋值 输出变量 default-- ...
- 使用es6的then()方法封装jquery的ajax请求
使用场景: jsp页面中使用jquery的ajax请求比较频繁,以前vue框架的项目用过axios,所以就想着用then()封装一个公共请求的方法,这样每次请求就不用那么麻烦的写一大堆请求参数了. 示 ...
- 337. House Robber III二叉树上的抢劫题
[抄题]: The thief has found himself a new place for his thievery again. There is only one entrance to ...
- [leetcode]84. Largest Rectangle in Histogram直方图中的最大矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- C#,如何程序使用正则表达式如何使用匹配的位置的结果修改匹配到的值
程序代码使用正则表达式如何修改匹配到的值: 代码一: using System; using System.Text.RegularExpressions; public class Example ...
- 将小程序的logo换成属于自己的头像
$logo = file_get_contents(IMG_URL.$logo); //根据头像的路径 $logo = yuanImg1($logo); //将头像改为圆形 $data = file_ ...