2013-08-08 4 views
2

Если у меня есть раскадровка, определенный как статический ресурс, например:Установка Storyboard.Targetname на раскадровке определяется как статический ресурс

<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> 

как я получаю ошибку

Прилагаемое свойство «Имя_целевого_объект» может быть применено только к типам, которые получены из «DependencyObject».

Есть ли аккуратный способ хранения моих раскадровки в качестве статических ресурсов, и они применяют их к элементам, как хотелось бы?

ответ

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" /> 
+0

Если это работает, купить себе пиво завтра :) Я просто думал, что я, возможно, придется написать пользовательский StoryBoard бегун. Спасибо за это – bradgonesurfing

+0

Это отлично работает. У меня был еще один вопрос о SO недавно о добавлении охранников/условий в раскадровку. Я подозреваю, что могу использовать этот трюк, чтобы сделать это тоже – bradgonesurfing

+1

Присоединенные свойства - это мощный способ расширения поведения элементов в WPF. Хотя они были формализованы как поведение Blend, в некоторых случаях проще просто сделать это по старой школе. Надеюсь, вы сможете применить эту технику, чтобы помочь вам решить еще несколько проблем! –

Смежные вопросы