次の問題は何日も私を悩ませてきました、しかし私はそれを最も単純な形に蒸留することができただけです。次のXAMLを検討してください。
<Window x:Class="VSMTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="CheckBox">
<Setter Property="Margin" Value="3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Grid x:Name="Root">
<Grid.Background>
<SolidColorBrush x:Name="brush" Color="White"/>
</Grid.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CheckStates">
<VisualStateGroup.Transitions>
<VisualTransition To="Checked" GeneratedDuration="00:00:03">
<Storyboard Name="CheckingStoryboard">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="brush" Storyboard.TargetProperty="Color">
<DiscreteColorKeyFrame KeyTime="0" Value="LightGreen"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
<VisualTransition To="Unchecked" GeneratedDuration="00:00:03">
<Storyboard Name="UncheckingStoryboard">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="brush" Storyboard.TargetProperty="Color">
<DiscreteColorKeyFrame KeyTime="0" Value="LightSalmon"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState Name="Checked">
<Storyboard Name="CheckedStoryboard" Duration="0">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="brush" Storyboard.TargetProperty="Color">
<DiscreteColorKeyFrame KeyTime="0" Value="Green"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState Name="Unchecked">
<Storyboard Name="UncheckedStoryboard" Duration="0">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="brush" Storyboard.TargetProperty="Color">
<DiscreteColorKeyFrame KeyTime="0" Value="Red"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<CheckBox x:Name="cb1">Check Box 1</CheckBox>
<CheckBox x:Name="cb2">Check Box 2</CheckBox>
<CheckBox x:Name="cb3">Check Box 3</CheckBox>
</StackPanel>
</Window>
CheckBox
バックグラウンドが状態に依存するように、コントロールを再テンプレート化するだけです。
- チェック済み=緑
- チェックなし=赤
- チェック(遷移)=ライトグリーン
- チェックを外す(遷移)=明るい赤
したがって、チェックボックスの1つをオンにすると、短時間は薄緑色に変わり、その後緑色に変わることが期待されます。同様に、チェックを外すと、短時間は明るい赤に変わり、その後赤に変わることが期待されます。
そしてそれは通常まさにそれをします。しかしいつもではない。
プログラムを十分に長くプレイすると(約30秒で取得できます)、トランジションアニメーションが視覚的な状態よりも優先される場合があります。つまり、チェックボックスは、選択されている場合は引き続き明るい緑色で表示され、選択されていない場合は明るい赤色で表示されます。これは、トランジションが実行するように構成された3秒後に撮影された、私が何を意味するかを示すスクリーンショットです。
これが発生したのは、コントロールがターゲット状態に正常に移行しなかったためではありません。それは正しい状態にあると主張します。デバッガーで次のことを確認して、これを確認しました(上のスクリーンショットに記載されている特定のケースの場合)。
var vsgs = VisualStateManager.GetVisualStateGroups(VisualTreeHelper.GetChild(this.cb2, 0) as FrameworkElement);
var vsg = vsgs[0];
// this is correctly reported as "Unselected"
var currentState = vsg.CurrentState.Name;
アニメーションのトレースを有効にすると、遷移が正常に完了すると次の出力が得られます。
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='44177654'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='UncheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='6148812'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='UncheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='8261103'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='36205315'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='UncheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='18626439'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 3 : Storyboard has been removed; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='44177654'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='UncheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'
System.Windows.Media.Animation Stop: 3 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='36893403'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='CheckingStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='49590434'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='<null>'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 3 : Storyboard has been removed; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='36893403'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='CheckingStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'
System.Windows.Media.Animation Stop: 3 :
System.Windows.Media.Animation Start: 3 : Storyboard has been removed; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='49590434'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='<null>'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'
System.Windows.Media.Animation Stop: 3 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='16977025'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='CheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 3 : Storyboard has been removed; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='16977025'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='CheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'
System.Windows.Media.Animation Stop: 3 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='16977025'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='CheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
また、遷移が正常に完了しなかった場合、次の出力が得られます。
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='44177654'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='UncheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='6148812'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='UncheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='8261103'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='36205315'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='UncheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='18626439'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 3 : Storyboard has been removed; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='44177654'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='UncheckedStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'
System.Windows.Media.Animation Stop: 3 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='36893403'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='CheckingStoryboard'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
System.Windows.Media.Animation Start: 1 : Storyboard has begun; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='49590434'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; StoryboardName='<null>'; TargetElement='System.Windows.Controls.Grid'; TargetElement.HashCode='41837403'; TargetElement.Type='System.Windows.Controls.Grid'; NameScope='<null>'
System.Windows.Media.Animation Stop: 1 :
最初の12行は遷移が成功したときとまったく同じですが、最後の10行は完全に欠落しています。
私は見つけたすべてのVSMドキュメントを読みましたが、この不安定な動作の説明を思い付くことができませんでした。
これはVSMのバグだと思いますか?この問題の既知の説明または回避策はありますか?