2

如果我将故事板定义为静态资源,例如:

<Storyboard
        x:Key="shakeAnimation"
    >
    <DoubleAnimationUsingKeyFrames
        Storyboard.TargetProperty="RenderTransform.X" 
        RepeatBehavior="5x"
        >
        <EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="3"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.15" Value="0"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.20" Value="-3"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.25" Value="0"/>
    </DoubleAnimationUsingKeyFrames>

</Storyboard>

并想申请我可以做的地方

<MultiDataTrigger.EnterActions >
     <BeginStoryboard>
         <StaticResource  
                         ResourceKey="shakeAnimation"/>
    </BeginStoryboard>
 </MultiDataTrigger.EnterActions>

我认为它有效。但是,如果我想将动画应用到特定对象,那么这不起作用

<MultiDataTrigger.EnterActions >
     <BeginStoryboard>
         <StaticResource Storyboard.TargetName="editWidget"  
                         ResourceKey="shakeAnimation"/>
    </BeginStoryboard>
 </MultiDataTrigger.EnterActions>

当我得到错误

附加属性“TargetName”只能应用于从“DependencyObject”派生的类型。

有没有一种巧妙的方法可以将我的故事板存储为静态资源,并将它们应用到我想要的元素上?

4

1 回答 1

3

我认为您将需要使用自定义附加属性来执行此操作。您将克隆Storyboard,并TargetName在克隆上设置 ,然后返回它。您的课程将如下所示:

public static class NamedStoryboard
{
    public static readonly DependencyProperty StoryboardProperty = DependencyProperty.RegisterAttached(
      "Storyboard",
      typeof(Storyboard),
      typeof(NamedStoryboard),
      new FrameworkPropertyMetadata(DoAttach));

    [AttachedPropertyBrowsableForType(typeof(BeginStoryboard))]
    public static Storyboard GetStoryboard(BeginStoryboard obj)
    {
        return (Storyboard)obj.GetValue(StoryboardProperty);
    }

    public static void SetStoryboard(BeginStoryboard obj, Storyboard value)
    {
        obj.SetValue(StoryboardProperty, value);
    }

    public static readonly DependencyProperty TargetNameProperty = DependencyProperty.RegisterAttached(
      "TargetName",
      typeof(string),
      typeof(NamedStoryboard),
      new FrameworkPropertyMetadata(DoAttach));

    [AttachedPropertyBrowsableForType(typeof(BeginStoryboard))]
    public static string GetTargetName(BeginStoryboard obj)
    {
        return (string)obj.GetValue(TargetNameProperty);
    }

    public static void SetTargetName(BeginStoryboard obj, string value)
    {
        obj.SetValue(TargetNameProperty, value);
    } 

    private static void DoAttach(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var begin = d as BeginStoryboard;
        if (begin == null) return;

        var sb = GetStoryboard(begin);
        if (sb == null) return;

        var name = GetTargetName(begin);
        if (string.IsNullOrEmpty(name))
            begin.Storyboard = sb;
        else
        {
            var clone = sb.Clone();
            Storyboard.SetTargetName(clone, name);
            begin.Storyboard = clone;
        }
    }
}

你会像这样使用它:

<BeginStoryboard local:NamedStoryboard.Storyboard="{StaticResource shakeAnimation}"
                 local:NamedStoryboard.TargetName="editWidget" />
于 2013-08-08T14:46:14.837 回答