2010-04-29 55 views
4

我正在尝试基于ViewModel中的属性更改创建一个简单的(我认为)动画效果。我希望目标是自定义控件的控件模板中的特定文本块,该控件从Window继承。WPF:选择动画的目标

从我看过的文章示例中,DataTrigger是实现此目的的最简单方法。看起来,Window.Triggers不支持DataTriggers,这导致我尝试在样式中应用触发器。我目前遇到的问题是我似乎无法定位TextBlock(或任何其他子控件) - 下面的代码是将动画应用于整个窗口的背景。

如果我完全离开StoryBoard.Target,效果完全一样。

这是错误语法的正确方法,还是有更简单的方法来实现这一点?

<Style x:Key="MyWindowStyle" TargetType="{x:Type Window}"> 
    <Setter Property="Template" Value="{StaticResource MyWindowTemplate}"/> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding ChangeOccurred}" Value="True"> 
      <DataTrigger.EnterActions> 
       <BeginStoryboard> 
        <Storyboard BeginTime="00:00:00" Duration="0:0:2" Storyboard.Target="{Binding RelativeSource={RelativeSource AncestorType=TextBlock}}" 
            Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> 
         <ColorAnimation FillBehavior="Stop" From="Black" To="Red" Duration="0:0:0.5" AutoReverse="True"/> 
        </Storyboard> 
       </BeginStoryboard> 
      </DataTrigger.EnterActions> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

更新

应该也提到,我试图命名的TextBlock,并通过StoryBoard.TargetName(如Timores建议)引用它,并得到了错误“的TargetName属性不能在一组风格二传手“。

+0

你想要的动画目标究竟是什么?你说*“自定义控件的控件模板中的特定文本块”*,但是为'Window'创建样式而不是自定义控件。你能提供包含动画目标的代码吗?上面的目标绑定不应该工作,因为我不指望Window有一个TextBlock类型的祖先,是吗?!这可能吗? – gehho 2010-04-30 07:01:54

+0

对不起,这是一个难以描述的设置。自定义控件*是一个窗口,因为它从窗口派生。安装程序/样式是由其他人创建的,所以我试图改进这个动画。 Textblock是一个子控件 - 再次查看它,RelativeSource/AncestorType可能不是很接近,因为我试图定位一个孩子而不是父母? – 2010-04-30 13:39:14

回答

4

编辑:我有监督的事实,TextBlock您的自定义窗口/控件的ControlTemplate。我不认为有可能从ControlTemplate的以外的StoryboardControlTemplate内控制。但是,您可以在您的自定义窗口中定义的属性,你那么数据绑定到你的ChangeOccurred属性,然后触发添加到您的ControlTemplate现在将获得由定制控件的属性触发,而不是窗口的视图模型的财产(当然,间接地是由ViewModel触发,因为ChangeOccurred绑定到自定义窗口的属性,这反过来触发动画 - 呃,复杂的句子,希望你能理解)。这是一个选项吗?你可以关注吗? ;-)

也许一些代码可以帮助:

public class MyCustomWindow : Window 
{ 
    public static readonly DependencyProperty ChangeOccurred2 = DependencyProperty.Register(...); 

    public bool ChangeOccurred2 { ... } 

    // ... 
} 

和一些XAML:

<local:MyCustomWindow ChangeOccurred2="{Binding ChangeOccurred}" ... > 
    <!-- Your content here... --> 
</local:MyCustomWindow> 

<!-- Somewhere else (whereever your ControlTemplate is defined) --> 
<ControlTemplate TargetType="{x:Type local:MyCustomWindow}"> 

    <!-- your template here --> 

    <ControlTemplate.Triggers> 
     <Trigger Property="ChangeOccurred2" Value="True"> 
      <Trigger.EnterActions> 
       <BeginStoryboard> 
        <Storyboard BeginTime="00:00:00" Duration="0:0:2" 
           Storyboard.TargetName="txtWhatever" 
           Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> 
         <ColorAnimation FillBehavior="Stop" 
             From="Black" To="Red" 
             Duration="0:0:0.5" 
             AutoReverse="True"/> 
        </Storyboard> 
       </BeginStoryboard> 
      </Trigger.EnterActions> 
     </Trigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 

注:我命名为窗口的属性ChangeOccurred2,因为我想它是从视图模型的区分ChangeOccurred财产。当然,你应该为这个属性选择一个更好的名字。但是,我错过了这样一个决定的背景。


我以前的答案:

所以,要动画一个TextBlock这在(自定义)窗口的内容?

为什么要在窗口上设置样式,而不是在TextBlock本身上?也许你应该尝试这样(没有测试这个!):

<local:MyCustomWindow ... > 
    <!-- ... --> 
    <TextBlock x:Name="textBlockAnimated" ... > 
     <TextBlock.Style> 
      <Style TargetType="{x:Type TextBlock}"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding ChangeOccurred}" Value="True"> 
         <DataTrigger.EnterActions> 
          <BeginStoryboard> 
           <Storyboard BeginTime="00:00:00" Duration="0:0:2" 
              Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> 
            <ColorAnimation FillBehavior="Stop" 
                From="Black" To="Red" 
                Duration="0:0:0.5" 
                AutoReverse="True"/> 
           </Storyboard> 
          </BeginStoryboard> 
         </DataTrigger.EnterActions> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </TextBlock.Style> 
    </TextBlock> 
    <!-- ... --> 
</local:MyCustomWindow> 

{Binding ChangeOccurred}可能是不够的。您可能需要将DataContext添加到TextBlock,或者添加RelativeSource或其他东西。

+0

您的更新答案有效!谢谢你的帮助。我觉得我接近它的方式倒退了,但我对WPF的造型/动画非常新颖。 – 2010-04-30 15:49:36

0

MyWindowTemplate中的TextBlock?

如果是这样,给TextBlock一个名称并使用Storyboard.TargetName来引用它。

another question in SO

+0

对不起,应该提到我试过并得到了:“TargetName属性不能在Style Setter上设置。” – 2010-04-29 20:38:40

+0

另外:是的,它在控制模板中。 – 2010-04-29 20:42:06