【问题标题】:Pause/Resume Storyboard not work暂停/恢复情节提要不起作用
【发布时间】:2017-11-22 09:52:21
【问题描述】:

我需要做什么:

  1. GotFocus 事件发生时,没有 MouseEnterMouseLeave 事件运行。

  2. LostFocusMouseEnterMouseLeave 事件之后再次激活。

鉴于需要,我写了如下代码,但是PauseResume的命令不起作用。

<ControlTemplate x:Key="SpecialNumber" TargetType="{x:Type TextBox}">
    <Grid>
        <Image x:Name="SpecialBg" Style="{DynamicResource CallStatusSpecialBg}"/>
        <Image x:Name="SpecialIBeam" Style="{DynamicResource CallStatusSpecialIBeam}" Source="../image/I-beam-b.png"/>
        <TextBox x:Name="SpecialText" Style="{DynamicResource CallStatusSpecialNumberText}" Text="5555" />
    </Grid>
    <ControlTemplate.Resources>
        <Storyboard x:Key="Hide">
            <DoubleAnimation Storyboard.TargetName="SpecialBg" Storyboard.TargetProperty="Opacity" Duration="0:0:0.4" To="0" />
            <DoubleAnimation Storyboard.TargetName="SpecialIBeam" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="0" />
            <DoubleAnimation Storyboard.TargetName="SpecialText" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="0" />
        </Storyboard>
        <Storyboard x:Key="ShowHalf">
            <DoubleAnimation Storyboard.TargetName="SpecialBg" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="1" />
            <DoubleAnimation Storyboard.TargetName="SpecialIBeam" Storyboard.TargetProperty="Opacity" Duration="0:0:0.4" To="1" />
            <DoubleAnimation Storyboard.TargetName="SpecialText" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="0.01" />
        </Storyboard>
        <Storyboard x:Key="Show">
            <DoubleAnimation Storyboard.TargetName="SpecialBg" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="1" />
            <DoubleAnimation Storyboard.TargetName="SpecialIBeam" Storyboard.TargetProperty="Opacity" Duration="0:0:0.4" To="1" />
            <DoubleAnimation Storyboard.TargetName="SpecialText" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="1" />
        </Storyboard>
    </ControlTemplate.Resources>
    <ControlTemplate.Triggers>

        <EventTrigger SourceName="SpecialText" RoutedEvent="UIElement.MouseEnter" >
            <EventTrigger.Actions>
                <BeginStoryboard Storyboard="{StaticResource ShowHalf}" x:Name="SpecialTextMouseEnter"/>
            </EventTrigger.Actions>
        </EventTrigger>

        <EventTrigger SourceName="SpecialText" RoutedEvent="UIElement.MouseLeave" >
            <EventTrigger.Actions>
                <BeginStoryboard Storyboard="{StaticResource Hide}" x:Name="SpecialTextMouseLeave"/>
            </EventTrigger.Actions>
        </EventTrigger>

        <EventTrigger SourceName="SpecialText" RoutedEvent="UIElement.GotFocus" >
            <EventTrigger.Actions>
                <PauseStoryboard BeginStoryboardName="SpecialTextMouseLeave" />
                <PauseStoryboard BeginStoryboardName="SpecialTextMouseEnter" />
                <BeginStoryboard Storyboard="{StaticResource Show}" x:Name="SpecialTextGotFocus"/>
            </EventTrigger.Actions>
        </EventTrigger>

        <EventTrigger SourceName="SpecialText" RoutedEvent="UIElement.LostFocus" >
            <EventTrigger.Actions>
                <ResumeStoryboard BeginStoryboardName="SpecialTextMouseLeave" />
                <ResumeStoryboard BeginStoryboardName="SpecialTextMouseEnter" />
                <BeginStoryboard Storyboard="{StaticResource Hide}" x:Name="SpecialTextLostFocus"/>
            </EventTrigger.Actions>
        </EventTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

【问题讨论】:

  • 复制一些相关的评论from MSDN“PauseStoryboard 仅在 Storyboard 处于活动状态时(在 Storyboard 启动后)影响”“当 BeginStoryboard 动作时在暂停后触发,它似乎恢复并重新启动”。这不是一个解决方案,但至少是一个问题描述
  • @grek40 谢谢。

标签: wpf xaml wpf-animation


【解决方案1】:

您可以使用简单的Trigger 和几个MultiTriggers,而不是使用EventTriggers,这样您就可以定义一个复杂的条件。

我有一个解决方案。

首先,将元素的默认Opacity 设置为0,因为这将是正确的初始状态:

<Image Opacity="0"/>
<Image Opacity="0" />
<TextBox Opacity="0" />

然后,定义将完成这项工作的触发器:

<ControlTemplate.Triggers>
    <!-- This trigger will unconditionally show the elements,
    if the text box has keyboard focus,
    and hide them, if the text box is not focused -->
    <Trigger Property="IsKeyboardFocusWithin" Value="True">
        <Trigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource Show}"/>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
            <BeginStoryboard Storyboard="{StaticResource Hide}"/>
        </Trigger.ExitActions>
    </Trigger>

    <!-- This trigger will partly show the elements, if the mouse cursor
    is over the text box, but it is not focused. If it's focused, then
    the previous trigger has already done its job -->
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="IsMouseOver" Value="True" />
            <Condition Property="IsKeyboardFocusWithin" Value="False"/>
        </MultiTrigger.Conditions>
        <MultiTrigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource ShowHalf}" x:Name="ShowHalfStoryboard" />                                
        </MultiTrigger.EnterActions>
        <MultiTrigger.ExitActions>
            <RemoveStoryboard BeginStoryboardName="ShowHalfStoryboard"/>
        </MultiTrigger.ExitActions>
    </MultiTrigger>

    <!-- This trigger will hide the elements, if the mouse cursor
    is outside the text box, and it is not focused. If it's focused, then
    the first trigger has already done its job. If it's not focused and
    the cursor is over the text box, then the previous trigger works. -->
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="IsMouseOver" Value="False" />
            <Condition Property="IsKeyboardFocusWithin" Value="False"/>
        </MultiTrigger.Conditions>
        <MultiTrigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource Hide}" x:Name="HideStoryboard" />
        </MultiTrigger.EnterActions>
        <MultiTrigger.ExitActions>
            <RemoveStoryboard BeginStoryboardName="HideStoryboard"/>
        </MultiTrigger.ExitActions>
    </MultiTrigger>

</ControlTemplate.Triggers>

【讨论】:

  • 感谢您提供有趣的解决方案;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 2017-05-29
  • 2017-08-03
  • 2014-06-30
  • 1970-01-01
  • 2012-12-31
相关资源
最近更新 更多