代码之家  ›  专栏  ›  技术社区  ›  Phil Sandler

WPF:选择动画的目标

  •  5
  • Phil Sandler  · 技术社区  · 16 年前

    我试图创建一个简单的(我认为)动画效果的基础上,在我的ViewModel属性的变化。我希望目标是自定义控件的控件模板中的一个特定textblock,该控件从Window继承。

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

    如果我完全不使用故事板。目标,效果完全一样。

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

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

    更新

    2 回复  |  直到 16 年前
        1
  •  5
  •   gehho    16 年前

    编辑: 我监督了这个事实 TextBlock ControlTemplate 自定义窗口/控件。我认为不可能以控制为目标 在内部 Storyboard 关于这个 控件模板 . 但是,可以在自定义窗口上定义一个属性,然后将其数据绑定到 ChangeOccurred 它现在将由自定义控件的属性而不是窗口的ViewModel属性触发(当然,它是由ViewModel间接触发的,因为 绑定到自定义窗口的属性,从而触发动画(呃,复杂的句子,希望您理解)。这是一种选择吗?你能跟着吗?;—)

    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 因为我想让它和ViewModel的 财产。当然,您应该为这个属性选择一个更好的名称。然而,我不知道这样一个决定的背景。


    我以前的回答是:

    控件 哪个在(自定义)窗口的内容中?!

    为什么要在窗口上设置样式,而不是在屏幕上 控件

    <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 控件 ,或添加 RelativeSource

        2
  •  0
  •   Community Mohan Dere    9 年前

    文本块是否在MyWindowTemplate中?

    如果是这样,请为TextBlock指定一个名称并使用Storyboard.TargetName引用它。

    看到了吗 another question in SO