WPF - No IsEnabled =使用带动画的样式的真实行为

时间:2009-06-08 19:50:58

标签: wpf animation styles isenabled

我问a question here但后来我意识到我的问题不是代码,而是我用于按钮的样式。由于问题与最初提出的问题完全不同,我认为如果我再次提出“正确”问题,对其他用户会更有利。我走了:

我在按钮中使用下面的模板。当我设置button.IsEnabled = false它工作正常,但如果我设置button.IsEnabled = true它不会启用。你能指出我做错了什么吗? 感谢

<Style x:Key="BlackButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="MouseOverActivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF2F2F2F"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.1270000" Value="#FF2391FF"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="MouseOverDeactivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="rectangle">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF2391FF"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.2200000" Value="#FF2F2F2F"/>

                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="PressActivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF2391FF"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.1370000" Value="#FF48D6FF"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="PressedDeactivating" FillBehavior="Stop" >
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="rectangle">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF48D6FF"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.2370000" Value="#FF2391FF"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="DisableActivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FFA7A7A7"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                </ControlTemplate.Resources>
                <Grid>
                    <Rectangle Stroke="Transparent" RadiusX="5" RadiusY="5" x:Name="rectangle">
                        <Rectangle.Fill>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#FF000000" Offset="0"/>
                                <GradientStop Color="#FF2F2F2F" Offset="1"/>
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True" OpacityMask="{x:Null}"/>
                    <Rectangle Stroke="Transparent" RadiusX="5" RadiusY="5" x:Name="WhiteGlow">
                        <Rectangle.Fill>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#5BFFFFFF" Offset="0"/>
                                <GradientStop Color="#00FFFFFF" Offset="0.5"/>
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsCancel" Value="False"/>
                    <EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
                    <Trigger Property="IsFocused" Value="True">
                        <Trigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverActivating}" x:Name="MouseOverActivating_BeginStoryboard2"/>
                        </Trigger.ExitActions>
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverActivating}" x:Name="MouseOverActivating_BeginStoryboard1"/>
                        </Trigger.EnterActions>
                    </Trigger>
                    <Trigger Property="IsDefaulted" Value="True"/>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Trigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverDeactivating}" x:Name="MouseOverDeactivating_BeginStoryboard"/>
                        </Trigger.ExitActions>
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverActivating}" x:Name="MouseOverActivating_BeginStoryboard"/>
                        </Trigger.EnterActions>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard x:Name="PressActivating_BeginStoryboard" Storyboard="{StaticResource PressActivating}"/>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <BeginStoryboard x:Name="PressedDeactivating_BeginStoryboard" Storyboard="{StaticResource PressedDeactivating}"/>
                        </Trigger.ExitActions>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource DisableActivating}" x:Name="DisableActivating_BeginStoryboard"/>
                        </Trigger.EnterActions>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

2 个答案:

答案 0 :(得分:1)

最简单的选择是添加一个动画,IsEnabled触发器ExitAction将恢复EnterAction中的动画

答案 1 :(得分:0)

我怀疑您看到的行为是IsEnabled变为false时使用的动画的结果。 DependencyProperties实际上具有与它们相关联的优先级,其中动画在列表中很高;该层次结构from MSDN是:

  
      
  • 物业系统强制
  •   
  • 动态动画或具有保留行为的动画。
  •   
  • 本地值
  •   
  • TemplatedParent模板属性
  •   
  • 隐含风格
  •   
  • 样式触发器
  •   
  • 模板触发器
  •   
  • 样式制定者
  •   
  • 默认(主题)风格
  •   
  • 从父
  • 继承   
  • 依赖项属性元数据的默认值
  •   

默认情况下,动画的HoldEnd为FillBehavior,这意味着它们会保持动画结束的值。当IsEnabled通过绑定变为True时,该更新发生在优先级的“本地值”级别,并且由于DisableActivating故事板将外观保持在更高的优先级(“具有保持行为的动画”),您永远不会看到按钮在第一次更改后会更改。

有三种解决方案:

  1. 更新动画以使FillBehavior为Stop,这意味着一旦动画停止,动画将不会声明'IsEnabled = False'视觉效果。您需要一个标准的非动画触发器,其状态与动画结束时相同,以便在动画完成后继续断言,否则您将看到它恢复到动画开始时的状态。 。由于它只是一个触发器设置,当更新本地值时,您将看到它像您期望的那样返回到原始值。此外,由于动画具有更高的优先级,您可以设置样式并同时启动动画,并且只在动画完成后“看到”样式的影响(因此您的淡入淡出将按预期工作)。
  2. 您可以创建一个新的触发器,在IsEnabled为True时应用(可能是瞬时)动画回原始状态,而不是更改FillBehavior。这也可以通过在触发器的ExitAction中应用动画来完成。由于它也是动画但后来应用,它将覆盖其他动画的HoldEnd状态。在某种意义上,这比选项1更容易,但是它可以成为维持正向和反向动画的麻烦,特别是如果你不需要反向动画来获得特定的视觉效果;但是,您可能希望保持淡出禁用状态。
  3. 将一个ExitAction添加到IsEnabled触发器以停止故事板,从而阻止动画继续断言它在动画结束时具有的值,以便可以应用本地值样式。此选项的好处是不必重复样式(如#1),同时也不必反转动画(如#2)。
  4. 在这三种解决方案中,最后一种解决方案可能是最简洁的(除非你有一个特定的原因,比如需要淡入淡出,更喜欢其他选项之一 - 或上述选项的组合)。