我在Button中有一个奇怪的故事板动画行为。
我调整了我的程序中已经使用的现有Button样式,以显示动画以通知用户正在进行的操作:一些新按钮在其特定点击事件中激活长时间运行序列(10秒)。我想直接在btnStyle中添加动画。
buttonClick事件启动一个方法,在第一行中我设置了按钮的attachProperty以启动动画,在最后一行中,attachProperty被重置。
奇怪的行为是动画NORMALLY不显示:只有在buttonClick事件方法的中间有一个System.Windows.MessageBox要求确认给用户的情况下才会显示它。
要调试这种情况,在我激活动画的代码中,我添加了Mouse.OverrideCursor = Cursors.Wait
:鼠标每次更改按钮事件(有或没有MEssageBox)。
为了添加测试,我在特定方法中分离了buttonClick事件代码,并且我也使用Dispatcher.BeginInvoke启动了它。
根本无法看到动画。
提前致谢....
这是情景:
1)在Windows中,我有一些按钮声明如下:
<Button Grid.Row="0" Grid.Column="1" Style="{DynamicResource btnStyle}" Name="btnCashQ_Report" Content="Stampa situazione" />
2)在资源文件中我声明了btnStyle:
<!-- STYLE BUTTON #START -->
<Style x:Key="btnStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="OuterBorder"
CornerRadius="3"
Background="{DynamicResource ButtonGradient}">
<Border
x:Name="InnerBorder"
CornerRadius="3"
Background="{DynamicResource ButtonUpGradient}"
Padding="{TemplateBinding Padding}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="12*" />
</Grid.ColumnDefinitions>
<ContentPresenter
x:Name="ContentSite"
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
>
<!-- $HELP: http://stackoverflow.com/questions/3970285/wpf-4-contentpresenter-textwrapping-style-is-not-applied-to-implicitedly-generat -->
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}" >
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="TextAlignment" Value="Center"/>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
<local:LoadingPanelSopra_6_12
x:Name="Animation"
Grid.Column="0"
AnimationEnable="{Binding Path=(buttonExt:WpfButtonExtensionsMethods.AnimationEnabled), RelativeSource={RelativeSource TemplatedParent}}"
/>
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="InnerBorder" Property="Background" Value="{DynamicResource ButtonDownGradient}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="InnerBorder" Property="Background" Value="{DynamicResource ButtonDisabledGradient}" />
<Setter Property="BorderBrush" Value="Silver" />
<Setter Property="Foreground" Value="SlateGray" />
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="buttonExt:WpfButtonExtensionsMethods.AnimationEnabled" Value="false"/>
<Setter Property="Foreground" Value="MidnightBlue" />
<Setter Property="FontFamily" Value="Segoe Black" />
<Setter Property="FontSize" Value="16px" />
<Setter Property="Margin" Value="5,5,5,5" />
<Setter Property="MinHeight" Value="25" />
<Setter Property="MaxHeight" Value="50" />
<Setter Property="MaxWidth" Value="250" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
在btnStyle
中,您可能会发现该按钮包含Grid
以安排ContentPresenter
来排列TextBox标题和LoadingPanelSopra_6_12
:这最后一个是我的自定义UserControl,使用StoryBoard Animation绘制带有小方块的圆弧。
动画由附加属性打开:
AnimationEnable="{Binding Path=(buttonExt:WpfButtonExtensionsMethods.AnimationEnabled), RelativeSource={RelativeSource TemplatedParent}}"
下面是usercontrol xaml(我剪切了重复的SplineColorKeyFrame标签)
<UserControl
x:Class="Svdh.SmStation.AutoCash.Biz.LoadingPanelSopra_6_12"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrls="clr-namespace:Svdh.Controls.WPF;assembly=Svdh.Controls.WPF"
xmlns:local="clr-namespace:Svdh.SmStation.AutoCash.Biz;assembly="
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:svdhAuto="clr-namespace:Svdh.Automation.Config;assembly=Svdh.Automation.Config"
mc:Ignorable="d"
d:Height="16"
d:Width="16" >
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Svdh.SmStation.AutoCash.Biz;Component/Resources/StylesThemeFree.xaml"/>
<ResourceDictionary Source="/Svdh.SmStation.AutoCash.Biz;component/Resources/Skin_Classic_Blue.xaml" />
<ResourceDictionary Source="/Svdh.SmStation.AutoCash.Biz;component/Resources/Skin_HighContrast_Yellow.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- ottimizzazione $HELP: http://mrpfister.com/journal/improving-wpf-rendering-performance/ -->
<Storyboard x:Key="ProgressAnimation_6_12" Completed="onStoryBoardCompleted" Timeline.DesiredFrameRate="5" RenderOptions.BitmapScalingMode="LowQuality">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block12" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#AA000000"/>
and so on....
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block11" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
and so on....
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#AA000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block10" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
and so on....
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#9B000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block9" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
and so on....
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#91000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block8" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#7F000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block7" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#72000000"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="block6" Storyboard.TargetProperty="(UIElement.OpacityMask).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:03.9000000" Value="#63000000"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</ResourceDictionary>
</UserControl.Resources>
<Canvas x:Name="LayoutRoot" Height="32" Width="88">
<Grid Width="10.734" Height="10.004" Canvas.Left="38.614" Canvas.Top="0.331">
<local:Block x:Name="block6" RenderTransformOrigin="0.5,4.3689" OpacityMask="#64000000" VerticalAlignment="Top" Height="10.004">
<local:Block.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-59.999999999999993"/>
<TranslateTransform/>
</TransformGroup>
</local:Block.RenderTransform>
</local:Block>
<local:Block x:Name="block7" RenderTransformOrigin="0.5,4.3689" OpacityMask="#72000000" VerticalAlignment="Top" Height="10.004">
<local:Block.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="-40"/>
<TranslateTransform/>
</TransformGroup>
</local:Block.RenderTransform>
</local:Block>
<local:Block x:Name="block8" RenderTransformOrigin="0.5,4.3689" OpacityMask="#80000000" VerticalAlignment="Top" Height="10.004">
<local:Block.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-19.999999999999996"/>
<TranslateTransform/>
</TransformGroup>
</local:Block.RenderTransform>
</local:Block>
<local:Block x:Name="block9" OpacityMask="#8E000000" RenderTransformOrigin="0.5,4.3689" VerticalAlignment="Top" Height="10.004"/>
<local:Block x:Name="block10" RenderTransformOrigin="0.5,4.3689" OpacityMask="#9C000000" VerticalAlignment="Top" Height="10.004">
<local:Block.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="19.999999999999996"/>
<TranslateTransform/>
</TransformGroup>
</local:Block.RenderTransform>
</local:Block>
<local:Block x:Name="block11" RenderTransformOrigin="0.5,4.3689" OpacityMask="#AA000000" VerticalAlignment="Top" Height="10.004">
<local:Block.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="0.99999999999999989" ScaleY="0.99999999999999989"/>
<SkewTransform/>
<RotateTransform Angle="40"/>
<TranslateTransform/>
</TransformGroup>
</local:Block.RenderTransform>
</local:Block>
<local:Block x:Name="block12" RenderTransformOrigin="0.5,4.3689" OpacityMask="#B8000000" VerticalAlignment="Top" Height="10.004">
<local:Block.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="59.999999999999993"/>
<TranslateTransform/>
</TransformGroup>
</local:Block.RenderTransform>
</local:Block>
</Grid>
</Canvas>
</UserControl>
要完成场景,请参阅usercontrol背后的代码,我在其中通过AttachedProperty AnimationEnabled
激活故事板动画
Public Shared ReadOnly AnimationEnableProperty As DependencyProperty = DependencyProperty.Register("AnimationEnable",
GetType(Boolean),
GetType(LoadingPanelSopra_6_12),
New PropertyMetadata(False, AddressOf OnDependencyPropertyChanged))
Public Property AnimationEnable As Boolean
Get
Return CBool(Me.GetValue(AnimationEnableProperty))
End Get
Set(value As Boolean)
Const METHOD_NAME As String = "AnimationEnable.SET()"
Try
Me.SetValue(AnimationEnableProperty, value)
Catch ex As Exception
Svdh.Dbg.IgnoreFirstChance(ex, Me, "{0}.ERL_{1}: ingored", METHOD_NAME, Erl.ToString)
End Try
End Set
End Property
调用
Private Shared Sub OnDependencyPropertyChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
Dim tbh As LoadingPanelSopra_6_12 = TryCast(d, LoadingPanelSopra_6_12)
Select Case e.Property.Name
Case "AnimationEnable"
tbh.AnimationEnable_Local = CBool(e.NewValue)
End Select
End Sub
谁有效地触发了有趣的代码
Private WriteOnly Property AnimationEnable_Local As Boolean
Set(value As Boolean)
If (value) Then
Me.Visibility = Windows.Visibility.Visible
Me.IsEnabled = True
Me.StartAnimation()
Else
Me.IsEnabled = True
Me.StopAnimation()
Me.Visibility = Windows.Visibility.Hidden
End If
End Set
End Property
序列中的最后一步是通过以下
进行Private Sub StartAnimation()
Dim SB As Storyboard = DirectCast(FindResource("ProgressAnimation_6_12"), Storyboard)
SB.Stop()
Mouse.OverrideCursor = Nothing
SB.Begin()
Mouse.OverrideCursor = Cursors.Wait
End Sub
Private Sub StopAnimation()
Dim SB As Storyboard = DirectCast(FindResource("ProgressAnimation_6_12"), Storyboard)
SB.Stop()
Mouse.OverrideCursor = Nothing
End Sub
Private Sub onStoryBoardCompleted(sender As Object, e As EventArgs)
Dim SB As Storyboard = DirectCast(FindResource("ProgressAnimation_6_12"), Storyboard)
If Me.AnimationEnable <> True Then
SB.Stop()
Mouse.OverrideCursor = Nothing
Else
SB.Begin()
Mouse.OverrideCursor = Cursors.Wait
End If
End Sub
正如我在前言中所说,Mouse.OverrideCursor = Cursors.Wait
和相对Mouse.OverrideCursor = Nothing
有效(鼠标显示正确),但相应的SB.Begin()
和SB.Stop()
实际上只在System.Windows.MessageBox显示在buttonClick事件方法的中间。
谢谢。