zoukankan      html  css  js  c++  java
  • WPF XAML Trigger中使用动画后 动画对象冻结的处理办法

    在编写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="128" >
                <local:ATCH.AniInvoke>
                    <Storyboard>
                        <Storyboard >
                            <DoubleAnimation From="20" To="300" Duration="0:0:01" Storyboard.TargetProperty="Width"  />
                        </Storyboard>
                    </Storyboard>
                </local:ATCH.AniInvoke>
    </Button>

    如果是想要搭配trigger来使用则是需要:

            <Button Height="128" >
                <Button.Resources>
                    <Storyboard x:Key="x">
                        <DoubleAnimation From="20" To="300" 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="220" To="440" 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="440" To="220" 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="128" Width="150">
                <Button.Resources>
                    <Storyboard x:Key="x"  >
                        <DoubleAnimation From="30" To="150" 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="128" Width="300">
                <Button.Resources>     
                    <Storyboard x:Key="x1">
                        <DoubleAnimation From="300" To="20"   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="20"  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="128" Width="300">
                <Button.Resources>
                    <Storyboard x:Key="x1">
                        <DoubleAnimation From="300" To="20"   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="20"  Margin="46,292,171,57">
                <Run>点击状态:</Run>
                <Run Text="{Binding ElementName=btn1, Path=IsPressed,Mode=OneWay}"></Run>
            </TextBlock>

  • 相关阅读:
    Linux查看磁盘空间大小
    Qt常见错误
    顺序查找和二分查找代码
    字典树——动态&&静态
    Linux本机和远程服务器之间文件的上传和下载 rz sz
    牛顿迭代法——C语言
    MFC之ListControl选中行删除
    MFC之登录框的问题处理
    MFC之创建多级动态菜单
    c++动态内存知识总结与疑问
  • 原文地址:https://www.cnblogs.com/T-ARF/p/10925941.html
Copyright © 2011-2022 走看看