我想在箭头图片(png)上运行一个简单的动画。箭头指向下方或向上,动画应该是指向它所指向的方向的箭头。
我使用Image控件并为其指定两种样式之一。这些样式定义了要使用的图片和故事板中的三个双动画。动画应该无条件地运行,就在图像创建的那一刻,永远。其中一种样式是向上箭头向上移动的箭头( Trend_Rising ),另一种样式是向下箭头指向下方的波形( Trend_Falling )。< / p>
以下是图像,并且样式位于从嵌入图像的UserControl引用的单独文件中。
<Image x:Name="TrendImg" Style="{DynamicResource Trend_Falling}" />
这是样式文件的内容:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="Trend_Base" TargetType="Image">
<Setter Property="OpacityMask">
<Setter.Value>
<LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
<GradientStop Color="Black" />
<GradientStop Color="Transparent" />
<GradientStop Color="Black" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Trend_Rising_Base" TargetType="Image" BasedOn="{StaticResource Trend_Base}">
<Style.Triggers>
<Trigger Property="IsVisible" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[0].Offset" From="-0.1" To="0.9" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[1].Offset" From="0.0" To="1.0" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[2].Offset" From="0.1" To="1.1" Duration="0:0:2" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="Trend_Falling_Base" TargetType="Image" BasedOn="{StaticResource Trend_Base}">
<Style.Triggers>
<Trigger Property="IsVisible" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[0].Offset" From="0.9" To="-0.1" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[1].Offset" From="1.0" To="0.0" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[2].Offset" From="1.1" To="0.1" Duration="0:0:2" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="Trend_Rising" TargetType="Image" BasedOn="{StaticResource Trend_Rising_Base}">
<Setter Property="Height" Value="16" />
<Setter Property="Source" Value="trend_rising.png" />
</Style>
<Style x:Key="Trend_Falling" TargetType="Image" BasedOn="{StaticResource Trend_Falling_Base}">
<Setter Property="Height" Value="16" />
<Setter Property="Source" Value="trend_falling.png" />
</Style>
</ResourceDictionary>
当我以编程方式更改样式时,动画不会改变。例如,如果我启动应用程序(图像分配了 Trend_Falling 样式),将显示向下箭头,波形动画向下移动。但是当我在运行时将样式更改为 Trend_Rising 时,箭头图片会按原样更改,但动画保持不变。
TrendImg.SetResourceReference(Control.StyleProperty, "Trend_Rising")
我做错了什么?我将不胜感激任何帮助。谢谢!
- 编辑 -
我创建了一个 ImageWithAnim 类,它是 Image 的后代,并为其添加了一个布尔 Animate 依赖项属性。然后我将触发器附加到该属性而不是 IsVisible 。 True启动故事板,false应该停止它,但它不会...当我将 Animate 设置为false时,会抛出一个异常,说明名称 RisingStoryboard 可以不能在命名空间 System.Windows.Style 中解析。我在StackOverflow上找到了几个帖子,根据这个帖子,这个例子应该可以工作(在声称它不会:-)的那些帖子中。
所以......现在我不知道怎么做对了。我将不胜感激任何帮助。谢谢!
这是更改的xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Test="clr-namespace:StyleChangeTest">
<Style x:Key="Trend_Base" TargetType="Test:ImageWithAnim">
<Setter Property="OpacityMask">
<Setter.Value>
<LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
<GradientStop Color="Black" />
<GradientStop Color="Transparent" />
<GradientStop Color="Black" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Trend_Rising_Base" TargetType="Test:ImageWithAnim" BasedOn="{StaticResource Trend_Base}">
<Style.Triggers>
<Trigger Property="Animate" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="RisingStoryboard">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[0].Offset" From="-0.1" To="0.9" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[1].Offset" From="0.0" To="1.0" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[2].Offset" From="0.1" To="1.1" Duration="0:0:2" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="Animate" Value="False">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="RisingStoryboard" />
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="Trend_Falling_Base" TargetType="Test:ImageWithAnim" BasedOn="{StaticResource Trend_Base}">
<Style.Triggers>
<Trigger Property="Animate" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="FallingStoryboard">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[0].Offset" From="0.9" To="-0.1" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[1].Offset" From="1.0" To="0.0" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[2].Offset" From="1.1" To="0.1" Duration="0:0:2" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="Animate" Value="False">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="FallingStoryboard" />
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="Trend_Rising" TargetType="Test:ImageWithAnim" BasedOn="{StaticResource Trend_Rising_Base}">
<Setter Property="Height" Value="16" />
<Setter Property="Source" Value="trend_rising.png" />
</Style>
<Style x:Key="Trend_Falling" TargetType="Test:ImageWithAnim" BasedOn="{StaticResource Trend_Falling_Base}">
<Setter Property="Height" Value="16" />
<Setter Property="Source" Value="trend_falling.png" />
</Style>
</ResourceDictionary>
这是 ImageWithAnim 类:
Public Class ImageWithAnim
Inherits Image
Private Shared _animate As DependencyProperty = DependencyProperty.Register("Animate",
GetType(Boolean),
GetType(ImageWithAnim),
New PropertyMetadata(defaultValue:=False))
Public Shared ReadOnly Property AnimateProperty As DependencyProperty
Get
Return _animate
End Get
End Property
Public Property Animate() As Boolean
Get
Return CBool(GetValue(_animate))
End Get
Set(value As Boolean)
SetValue(_animate, value)
End Set
End Property
End Class
答案 0 :(得分:1)
巧合的是,我刚刚找到了自己问题的答案。故事板的名称无法解析,因为它们是在基本样式中定义的。当我直接在我感兴趣的两种风格中定义它们时,我可以按预期使用 ImageWithAnim 的 Animate 属性启动和停止它们,没有任何例外。
因此,在更改图像样式时,我必须执行以下操作:
TrendImg.Animate = False
TrendImg.SetResourceReference(ImageWithAnim.StyleProperty, "Trend_Falling")
TrendImg.Animate = True
现在动画被正确更改,波浪动画按箭头指向的方向移动,这就是我想要实现的目标。
以下是改变后的风格:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Test="clr-namespace:StyleChangeTest">
<Style x:Key="Trend_Base" TargetType="Test:ImageWithAnim">
<Setter Property="OpacityMask">
<Setter.Value>
<LinearGradientBrush StartPoint="0,1" EndPoint="0,0">
<GradientStop Color="Black" />
<GradientStop Color="Transparent" />
<GradientStop Color="Black" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Trend_Rising" TargetType="Test:ImageWithAnim" BasedOn="{StaticResource Trend_Base}">
<Setter Property="Height" Value="16" />
<Setter Property="Source" Value="trend_rising.png" />
<Style.Triggers>
<Trigger Property="Animate" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="RisingStoryboard">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[0].Offset" From="-0.1" To="0.9" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[1].Offset" From="0.0" To="1.0" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[2].Offset" From="0.1" To="1.1" Duration="0:0:2" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="RisingStoryboard" />
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="Trend_Falling" TargetType="Test:ImageWithAnim" BasedOn="{StaticResource Trend_Base}">
<Setter Property="Height" Value="16" />
<Setter Property="Source" Value="trend_falling.png" />
<Style.Triggers>
<Trigger Property="Animate" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="FallingStoryboard">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[0].Offset" From="0.9" To="-0.1" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[1].Offset" From="1.0" To="0.0" Duration="0:0:2" RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="OpacityMask.GradientStops[2].Offset" From="1.1" To="0.1" Duration="0:0:2" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="FallingStoryboard" />
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
并解释为什么我在开始时将故事板放在基本样式中。问题是,在我的原始应用程序中,我有几个不同的箭头图片,并且只是不想重复故事板定义。但似乎我必须这样做。