【问题标题】:WPF scaleX and scaleY animationWPF scaleX 和 scaleY 动画
【发布时间】:2020-09-18 15:44:13
【问题描述】:

我正在尝试在椭圆上设置 scaleX 和 scaleY 动画。
只是我想在 2 种情况下对 scaleX 和 scaleY 进行动画处理:

  • 当背景为绿色时,我想将 scaleX 和 scaleY 从 0 变为 1。
  • 当背景为红色时,我想将 scaleX 和 scaleY 从 1 变为 0

由于某种原因,从 0 到 1 的缩放动画成功,而从 1 到 0 的缩放动画根本不起作用。

代码示例:

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800"
    DataContext="{Binding Source={StaticResource Locator}, Path=Main}">
<Window.Resources>
    <Storyboard x:Key="CheckedEllipseON">
        <DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleX" Storyboard.TargetName="CheckedEllipseScale">
            <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.0" />
            <LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.1" />
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleY" Storyboard.TargetName="CheckedEllipseScale">
            <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.0" />
            <LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.1" />
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="CheckedEllipseOFF">
        <DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleX" Storyboard.TargetName="CheckedEllipseScale">
            <LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.0" />
            <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.1" />
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleY" Storyboard.TargetName="CheckedEllipseScale">
            <LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.0" />
            <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.1" />
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

    <Style TargetType="ToggleButton" x:Key="MyToggleButtonStyle">
        <Setter Property="Foreground" Value="Black"/>
        <Setter Property="Width" Value="40"/>
        <Setter Property="Height" Value="40"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Grid ClipToBounds="True" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">                            
                        <Ellipse Fill="Green" x:Name="CheckedEllipse" RenderTransformOrigin="0.5, 0.5">
                            <Ellipse.RenderTransform>
                                <ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="1.0" ScaleY="1.0" x:Name="CheckedEllipseScale"/>
                            </Ellipse.RenderTransform>
                        </Ellipse>
                        <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                    </Grid>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding Background,RelativeSource={RelativeSource Mode=Self}}" Value="Red">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource CheckedEllipseOFF}"/>
                            </DataTrigger.EnterActions>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Background,RelativeSource={RelativeSource Mode=Self}}" Value="Green">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource CheckedEllipseON}"/>
                            </DataTrigger.EnterActions>
                        </DataTrigger>                            
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid>
    <ToggleButton>
        <ToggleButton.Style>
            <Style TargetType="ToggleButton" BasedOn="{StaticResource MyToggleButtonStyle}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Test}" Value="true">
                        <Setter Property="Background" Value="Green"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Test}" Value="false">
                        <Setter Property="Background" Value="Red"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ToggleButton.Style>
    </ToggleButton>
    <Button Command="{Binding TestCommand}" VerticalAlignment="Bottom" Width="100" Height="50"/>
</Grid>
  • Test 属性和 TestCommand 仅用于通过布尔属性更改绿色和红色。

谢谢。

【问题讨论】:

    标签: c# wpf xaml animation


    【解决方案1】:

    您发布的代码中实际上存在两个不同的问题。首先,您的椭圆背景明确设置为"Green",因此实际上永远不会变为红色。这是“本地设置”属性优先于样式或触发器设置器的情况。

    这可以通过更改椭圆声明来解决:

    <Ellipse Fill="{TemplateBinding Background}"
             x:Name="CheckedEllipse"
             RenderTransformOrigin="0.5, 0.5">
    

    这将导致椭圆从模板化的父级继承背景值。

    该问题仅影响显示的颜色。您使用的触发器使用ToggleButton.Background,因此不受该问题的影响。那么,为什么动画只在一个方向起作用呢?

    这个问题是因为您没有在开始另一个动画之前停止一个动画。动画的默认值是保持其先前的值,因此一旦动画运行以增加比例,它会继续保持该比例值,导致其他动画减小比例的尝试被覆盖和忽略。

    您可以通过将&lt;StopStoryboard/&gt; 操作添加到触发器来修复该方面:

    <ControlTemplate.Triggers>
      <DataTrigger Binding="{Binding Background,RelativeSource={RelativeSource Mode=Self}}" Value="Red">
        <DataTrigger.EnterActions>
          <StopStoryboard BeginStoryboardName="StoryON"/>
          <BeginStoryboard Storyboard="{StaticResource CheckedEllipseOFF}" Name="StoryOFF"/>
        </DataTrigger.EnterActions>
      </DataTrigger>
      <DataTrigger Binding="{Binding Background,RelativeSource={RelativeSource Mode=Self}}" Value="Green">
        <DataTrigger.EnterActions>
          <StopStoryboard BeginStoryboardName="StoryOFF"/>
          <BeginStoryboard Storyboard="{StaticResource CheckedEllipseON}" Name="StoryON"/>
        </DataTrigger.EnterActions>
      </DataTrigger>
    </ControlTemplate.Triggers>
    
    

    请注意,您还必须为 started 故事板命名,以便以后可以使用该名称来停止它。

    通过这些更改,我可以单击按钮来切换椭圆的比例,使其在绿色时增大,在红色时减小(并消失)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-09
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多