WPF XAML Trigger中使用动画后 动画对象冻结的处理办法
2024-09-02 03:11:18
在编写XAML时
在Trigger中使用动画,在动画之后,动画对象就会被冻结,无法被其他动画或者属性改变。
处理办法有:
1 使用附加属性来添加动画
public static readonly DependencyProperty AniInvokePropery = DependencyProperty.RegisterAttached("AniInvoke", typeof(Storyboard), typeof(ATCH), new PropertyMetadata(null, AniInvokeCallBack)); public static void SetAniInvoke(DependencyObject d, Storyboard value) => d.SetValue(AniInvokePropery, value); public static Storyboard GetAniInvoke(DependencyObject d) => (Storyboard)d.GetValue(AniInvokePropery); private static void AniInvokeCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var t = d as FrameworkElement; var s = (Storyboard)e.NewValue; if (s != null)
t.BeginStoryboard(s);
}
xaml
<Button Height="" >
<local:ATCH.AniInvoke>
<Storyboard>
<Storyboard >
<DoubleAnimation From="" To="" Duration="0:0:01" Storyboard.TargetProperty="Width" />
</Storyboard>
</Storyboard>
</local:ATCH.AniInvoke>
</Button>
如果是想要搭配trigger来使用则是需要:
<Button Height="" >
<Button.Resources>
<Storyboard x:Key="x">
<DoubleAnimation From="" To="" Duration="0:0:01" Storyboard.TargetProperty="Width" />
</Storyboard>
</Button.Resources>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="local:ATCH.AniInvoke" Value="{StaticResource x}"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
2 依赖属性来增加动画
依赖属性相对附加属性而言,在MVVM模式也是非常的引用
public static readonly DependencyProperty AniInvokeProperty= DependencyProperty.Register("AniInvoke", typeof(Storyboard), typeof(SearchViewPage), new PropertyMetadata(null, AniInvokeCallBack)); private static void AniInvokeCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var b = d as SearchViewPage;
var s = (Storyboard)e.NewValue;
if(s!=null)
b.BeginStoryboard(s);
}
xaml( 涉及其他代码,只是截取部分,这个部分是style的trigger)
<DataTrigger Binding="{Binding ElementName=SearchBox,Path=Tag}" Value="false">
<Setter Property="Tag" Value="T1"/>
<Setter Property="AniInvoke">
<Setter.Value>
<Storyboard>
<DoubleAnimation From="" To="" Duration="0:0:00.5" Storyboard.TargetProperty="Width"/>
</Storyboard>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=SearchBox,Path=Tag}" Value="true">
<Setter Property="Tag" Value="T2"/>
<Setter Property="AniInvoke">
<Setter.Value>
<Storyboard>
<DoubleAnimation From="" To="" Duration="0:0:00.5" Storyboard.TargetProperty="Width"/>
</Storyboard>
</Setter.Value>
</Setter>
</DataTrigger>
3使用storybroad的FillBehavior
FillBehavior有两个值一个是Stop和HoldEnd
HoldEnd是默认值,也就是维持动画结束后的状态
Stop则是取消动画后的状态
启用stop后 在其他地方设置width时是可以改变的,具体看依赖属性的优先级
<Button Height="" Width="">
<Button.Resources>
<Storyboard x:Key="x" >
<DoubleAnimation From="" To="" Duration="0:0:01" FillBehavior="Stop" Storyboard.TargetProperty="Width" />
</Button.Resources>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="false">
<Trigger.EnterActions>
<BeginStoryboard Name="s1" Storyboard="{StaticResource x}">
</BeginStoryboard>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
4通过情节动画的StopStoryboard来停止动画
这个则是需要使用其他的触发器配合或者是使用EnterActions和ExitActions的方式
EnterActions是触发器活跃时启动的方法,也就是触发器触发时
ExitActions是触发器不活跃时启动,注意不活跃是本触发器活跃后或者触发条件为相反时
(1)其他触发器配合:
<Button x:Name="btn1" Height="" Width="">
<Button.Resources>
<Storyboard x:Key="x1">
<DoubleAnimation From="" To="" Duration="0:0:01" Storyboard.TargetProperty="Width" />
</Storyboard>
</Button.Resources>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="bs2" Storyboard="{StaticResource x1}">
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsPressed" Value="false">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="bs2"/>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<TextBlock FontSize="" Margin="46,292,171,57">
<Run>点击状态:</Run>
<Run Text="{Binding ElementName=btn1, Path=IsPressed,Mode=OneWay}"></Run>
</TextBlock>
注意鼠标要在触发区域内
(2)通过EnterAction和ExitAction
<Button x:Name="btn1" Height="" Width="">
<Button.Resources>
<Storyboard x:Key="x1">
<DoubleAnimation From="" To="" Duration="0:0:01" FillBehavior="HoldEnd" Storyboard.TargetProperty="Width" />
</Storyboard>
</Button.Resources>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="bs2" Storyboard="{StaticResource x1}">
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="bs2"/>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<TextBlock FontSize="" Margin="46,292,171,57">
<Run>点击状态:</Run>
<Run Text="{Binding ElementName=btn1, Path=IsPressed,Mode=OneWay}"></Run>
</TextBlock>
最新文章
- python之三层菜单递归
- apache(nginx)+django+virutalenv(virtualenvwrapper)+gunicorn+supervisor配置高效web环境
- UITextView实现placeHolder方法汇总
- nginx反向代理、优化
- spring的懒加载
- The C++ Standard Library --- A Tutorial Reference 读书笔记
- ***iOS开发中@selector的理解与应用
- SQL Server 自定义快捷键
- ECP系统J2EE架构开发平台
- SLAM+语音机器人DIY系列:(四)差分底盘设计——5.底盘PID控制参数整定
- select2 插件加载后端数据
- inux进程/线程调度策略与 进程优先级
- Mac配置Jdk 安装及系统环境配置
- AtCoder Grand Contest 002 (AGC002) F - Leftmost Ball 动态规划 排列组合
- Delphi如何处理在进行大量循环时,导致的应用程序没有响应的情况
- leetcode617
- html5 sessionStorage VS loaclStorage
- JVM常用工具使用之jmap
- orcale字段
- 【刷题】BZOJ 4827 [Hnoi2017]礼物