内容简介:UWP里有一件非常令人不爽的事,大部分控件只提供了Normal状态下的Background,Foreground,BorderBrush,而控件一般至少具有Normal、PointerOver、Pressed、Disabled,ItemContainerStyle还有Selected、PointerOverSelected、PressedSelected这几种。那么常规方法怎么修改这几个状态内的值呢?当然是贴一遍又臭又长的Style。那如果有很多不是很一样的控件,除了修改模板或者自定义一个控件之外,有没有
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" />
以上所述就是小编给大家介绍的《不修改模板的前提下修改VisualState中的某些值》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 巴比特专栏 | 谷燕西:合理的项目范围是稳定币项目成功的前提
- 微软超融合私有云测试31-SCCM2016部署之前提条件准备、SQL部署
- 修改Git已提交的的Author和EMail(批量修改脚本)
- ViewGroup 默认顺序绘制子 View,如何修改?什么场景需要修改绘制顺序?
- Per.js 史上最大修改版本,2.1 版本更新,修改 5 项功能
- 通过修改环境变量修改当前进程使用的系统 Temp 文件夹的路径
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
构建之法(第三版)
邹欣 / 人民邮电出版社 / 2017-6 / 69.00元
软件工程牵涉的范围很广, 同时也是一般院校的同学反映比较空洞乏味的课程。 但是,软件工程 的技术对于投身 IT 产业的学生来说是非常重要的。作者有在世界一流软件企业 20 年的一线软件开 发经验,他在数所高校进行了多年的软件工程教学实践,总结出了在 16 周的时间内让同学们通过 “做 中学 (Learning By Doing)” 掌握实用的软件工程技术的教学计划,并得到高校师生的积极反馈。在此 ......一起来看看 《构建之法(第三版)》 这本书的介绍吧!