代码之家  ›  专栏  ›  技术社区  ›  Miral

初始值不起作用的交互数据触发器

  •  0
  • Miral  · 技术社区  · 6 年前

    我正在尝试创建一个WPF(4.6.2)数据模板,该模板将在特定的ViewModel属性设置为true时执行动画,然后在动画完成后(不仅仅是在启动时)将该属性设置为false。

    这是一次尝试:

    <DataTemplate DataType="...">
        <Border x:Name="Bd" ...>
            <Border.Resources>
                <Storyboard x:Key="Animate" FillBehavior="Stop">
                    <DoubleAnimation Storyboard.TargetName="Bd"
                                     Storyboard.TargetProperty="Opacity"
                                     From="0" To="1" Duration="0:0:3" />
                </Storyboard>
            </Border.Resources>
            ...
            <i:Interaction.Triggers>
                <ei:DataTrigger Binding="{Binding ShouldAnimate}" Value="true">
                    <ei:ControlStoryboardAction Storyboard="{StaticResource Animate}"
                                                ControlStoryboardOption="Play" />
                </ei:DataTrigger>
                <ei:StoryboardCompletedTrigger Storyboard="{StaticResource Animate}">
                    <ei:ChangePropertyAction TargetObject="{Binding}"
                                             PropertyName="ShouldAnimate"
                                             Value="false" />
                </ei:StoryboardCompletedTrigger>
            </i:Interaction.Triggers>
        </Border>
    </DataTemplate>
    

    这很管用…前提是我只将属性设置为true 之后 它已经创建了用户界面。如果属性已经为true,则不会发生任何事情(情节提要未启动,属性未重置)。

    (我也不太高兴必须将故事板声明为本地资源,以便targetname可以工作,但这似乎是必需的。)

    另一个尝试是使用普通的数据触发器:

        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding ShouldAnimate}" Value="true">
                <DataTrigger.EnterActions>
                    <BeginStoryboard Storyboard="{StaticResource Animate}" />
                </DataTrigger.EnterActions>
            </DataTrigger>
        </DataTemplate.Triggers>
    

    这可以成功地设置动画,即使属性是预先设置的(尽管奇怪的是,这个属性 Storyboard.TargetName 必须是 指定,并且故事板本身必须完全声明在 DataTemplate 或嵌入到 BeginStoryboard 而不是使用资源)。但在动画完成时,我找不到任何好的方法来重置属性。

    Storyboard.Completed 一开始看起来很有希望,但是它似乎不包含任何上下文信息,比如它调用了哪个实例,因此需要更新哪个视图模型。(看起来像 StoryboardCompletedTrigger 在内部使用它,但依赖于本地故事板实例而不是全局资源。我还没有用多个模板实例测试过这个,但重要的是,在一个模板上完成的故事板不会影响另一个模板。)


    我尝试结合这两种方法(在普通的数据触发器中启动故事板,在交互触发器中等待完成),但这会导致 StoryboardCompletedTrigger.Storyboard 若要引发分析错误,在尝试附加到已完成的事件处理程序时,“Storyboard must have isfrozed set to false to modify”;可能是因为将普通触发器作为样式应用。

    0 回复  |  直到 6 年前