内容简介: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 文件夹的路径
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Masterminds of Programming
Federico Biancuzzi、Chromatic / O'Reilly Media / 2009-03-27 / USD 39.99
Description Masterminds of Programming features exclusive interviews with the creators of several historic and highly influential programming languages. Think along with Adin D. Falkoff (APL), Jame......一起来看看 《Masterminds of Programming》 这本书的介绍吧!
HEX CMYK 转换工具
HEX CMYK 互转工具
HSV CMYK 转换工具
HSV CMYK互换工具