使用VisualStateManager启动和停止故事板 [英] Using VisualStateManager to start and stop Storyboards
问题描述
我有,它通过将360度无限(它基本上旋转),动画一个画布
动画。我要的是这个动画时,将显示控制和当控制隐藏启动然后停止。我想我可以配合这,不知何故,到 VisualStateManager
。我看到进出管制的这里它可以工作,但我只是不知道如何使用VSM启动和停止故事板
< Canvas.Resources>
<情节提要X:NAME =spinnerBoard>
< DoubleAnimation是
Storyboard.TargetName =SpinnerRotate
Storyboard.TargetProperty =角度
从=0=360时长=0:0: 01.3
的repeatBehavior =永远/>
< /故事板>
< /Canvas.Resources>
< Canvas.RenderTransform>
< RotateTransform X:NAME =SpinnerRotate角度=0/>
< /Canvas.RenderTransform>
例VSM
<的VisualState X:名称=显示>
<情节提要>
<! - 从这里开始故事板 - >
< /故事板>
< /&的VisualState GT;
<的VisualState X:NAME =隐藏>
<情节提要>
<! - 在这里停止故事板 - >
< /故事板>
< /&的VisualState GT;
您不同的问题一个全球性的答案:结果
ExtendedVisualStateManager.GoToElementState在Silverlight 结果$ b返回false $ b 默认绑定到用户控件定制DP
您可以做这样的事情:
- 使用扩展模板控制
ContentControl中
与
玩IsEnabled
的含量(防止等待时的动作的); - 创建一个DP
IsWaiting
的切换你的控制可视状态; - 创建XAML中的两种状态:使用
DoubleAnimation是
与的repeatBehavior =永远
后,您可以添加一个叠加和等待消息依赖属性像繁忙的指标控制...
我用图片为等待视觉部分但你可以用画布,网格等...
C#
[TemplateVisualState(组名=WaitGroup,名称= WaitSpinner.IsWaitingStateName)]
[TemplateVisualState(组名=WaitGroup,名称= WaitSpinner.NotWaitingStateName)]
公类WaitSpinner:ContentControl中
{
#地区国家的名字
内部常量字符串IsWaitingStateName =IsWaitingState;
内部常量字符串NotWaitingStateName =NotWaitingState;
#endregion国名
公共BOOL IsWaiting
{
{返回(布尔)的GetValue(IsWaitingProperty); }
集合{的SetValue(IsWaitingProperty,值); }
}
公共静态只读的DependencyProperty IsWaitingProperty =
DependencyProperty.Register(IsWaiting的typeof(布尔)的typeof(WaitSpinner),新PropertyMetadata(假,OnIsWaitingPropertyChanged)) ;
私有静态无效OnIsWaitingPropertyChanged(DependencyObject的发件人,DependencyPropertyChangedEventArgs E)
{
WaitSpinner waitSpinner =(WaitSpinner)发送;
waitSpinner.ChangeVisualState(真);
}
公共WaitSpinner()
{
DefaultStyleKey = typeof运算(WaitSpinner);
}
公共覆盖无效OnApplyTemplate()
{
base.OnApplyTemplate();
ChangeVisualState(假);
}
受保护的虚拟无效ChangeVisualState(布尔useTransitions)
{
VisualStateManager.GoToState(这一点,IsWaiting IsWaitingStateName:NotWaitingStateName,useTransitions);
}
}
的XAML:
< VisualStateGroup X:NAME =WaitGroup>
<的VisualState X:NAME =NotWaitingState>
<情节提要>
< ObjectAnimationUsingKeyFrames Storyboard.TargetProperty =(Control.IsEnabled)Storyboard.TargetName =内容>
将; DiscreteObjectKeyFrame KeyTime =0>
< DiscreteObjectKeyFrame.Value>
<系统:布尔>真< /系统:布尔>
< /DiscreteObjectKeyFrame.Value>
< / DiscreteObjectKeyFrame>
< / ObjectAnimationUsingKeyFrames>
< /故事板>
< /&的VisualState GT;
<的VisualState X:NAME =IsWaitingState>
<情节提要>
< ObjectAnimationUsingKeyFrames Storyboard.TargetProperty =(UIElement.Visibility)Storyboard.TargetName =WaitPart>
< DiscreteObjectKeyFrame KeyTime =0:0:0.200VALUE =可见/>
< / ObjectAnimationUsingKeyFrames>
< DoubleAnimation是Storyboard.TargetProperty =(UIElement.RenderTransform)(RotateTransform.Angle)。Storyboard.TargetName =WaitPart为了=360的repeatBehavior =永远时间=0:0:1 />
< ObjectAnimationUsingKeyFrames Storyboard.TargetProperty =(Control.IsEnabled)Storyboard.TargetName =内容>
将; DiscreteObjectKeyFrame KeyTime =0>
< DiscreteObjectKeyFrame.Value>
<系统:布尔>假LT; /系统:布尔>
< /DiscreteObjectKeyFrame.Value>
< / DiscreteObjectKeyFrame>
< / ObjectAnimationUsingKeyFrames>
< /故事板>
< /&的VisualState GT;
< / VisualStateGroup>
<! - ............. - >
< ContentControl中
IsTabStop =FALSE
X:NAME =内容
含量={TemplateBinding内容}
的ContentTemplate ={TemplateBinding的ContentTemplate}
HorizontalContentAlignment ={TemplateBinding HorizontalContentAlignment}
VerticalContentAlignment ={TemplateBinding VerticalContentAlignment}
前景={TemplateBinding前景}
ScrollViewer.HorizontalScrollBarVisibility ={TemplateBinding ScrollViewer.HorizontalScrollBarVisibility }
ScrollViewer.VerticalScrollBarVisibility ={TemplateBinding ScrollViewer.VerticalScrollBarVisibility}/>
<图像源=CirclePicture.png
X:NAME =WaitPart
RenderTransformOrigin =0.5,0.5
WIDTH =16
高度= 16
能见度=坍塌
IsHitTestVisible =FALSE>
< Image.RenderTransform>
< RotateTransform />
< /Image.RenderTransform>
< /图像>
I have an animation that animates a Canvas
by turning it 360 degrees indefinitely (it basically spins). What I want is for this animation to start when the control is shown and then stop when the control is hidden. I figured I could tie this in, somehow, to the VisualStateManager
. I have seen an example of fading in and out controls here which could work but I just dont know how to use VSM to start and stop the storyboard
<Canvas.Resources>
<Storyboard x:Name="spinnerBoard">
<DoubleAnimation
Storyboard.TargetName="SpinnerRotate"
Storyboard.TargetProperty="Angle"
From="0" To="360" Duration="0:0:01.3"
RepeatBehavior="Forever" />
</Storyboard>
</Canvas.Resources>
<Canvas.RenderTransform>
<RotateTransform x:Name="SpinnerRotate" Angle="0" />
</Canvas.RenderTransform>
Example VSM
<VisualState x:Name="Show">
<Storyboard>
<!-- Start the story board here -->
</Storyboard>
</VisualState>
<VisualState x:Name="Hide">
<Storyboard>
<!-- Stop the story board here -->
</Storyboard>
</VisualState>
A global answer of your different questions :
ExtendedVisualStateManager.GoToElementState returns false in Silverlight
Default binding to UserControl for custom DP
You can do something like this :
- Use a template control that extend
ContentControl
to play withIsEnabled
of content (prevent action during waiting) ; - Create a DP
IsWaiting
that switch your control visual state ; - Create the two states in XAML : Use
DoubleAnimation
withRepeatBehavior="Forever"
After you can add a overlay and a Waiting message dependency property like the busy indicator control...
I use a picture for the Waiting visual part but you can use a canvas, grid etc...
C#
[TemplateVisualState(GroupName = "WaitGroup", Name = WaitSpinner.IsWaitingStateName)]
[TemplateVisualState(GroupName = "WaitGroup", Name = WaitSpinner.NotWaitingStateName)]
public class WaitSpinner : ContentControl
{
#region States names
internal const String IsWaitingStateName = "IsWaitingState";
internal const String NotWaitingStateName = "NotWaitingState";
#endregion States names
public bool IsWaiting
{
get { return (bool)GetValue(IsWaitingProperty); }
set { SetValue(IsWaitingProperty, value); }
}
public static readonly DependencyProperty IsWaitingProperty =
DependencyProperty.Register("IsWaiting", typeof(bool), typeof(WaitSpinner), new PropertyMetadata(false, OnIsWaitingPropertyChanged));
private static void OnIsWaitingPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
WaitSpinner waitSpinner = (WaitSpinner)sender;
waitSpinner.ChangeVisualState(true);
}
public WaitSpinner()
{
DefaultStyleKey = typeof(WaitSpinner);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
ChangeVisualState(false);
}
protected virtual void ChangeVisualState(bool useTransitions)
{
VisualStateManager.GoToState(this, IsWaiting ? IsWaitingStateName : NotWaitingStateName, useTransitions);
}
}
Xaml :
<VisualStateGroup x:Name="WaitGroup">
<VisualState x:Name="NotWaitingState" >
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.IsEnabled)" Storyboard.TargetName="content">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<System:Boolean>True</System:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="IsWaitingState">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="WaitPart">
<DiscreteObjectKeyFrame KeyTime="0:0:0.200" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)" Storyboard.TargetName="WaitPart" To="360" RepeatBehavior="Forever" Duration="0:0:1" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.IsEnabled)" Storyboard.TargetName="content">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<System:Boolean>False</System:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<!-- ............. -->
<ContentControl
IsTabStop="False"
x:Name="content"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}"
ScrollViewer.HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
ScrollViewer.VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"/>
<Image Source="CirclePicture.png"
x:Name="WaitPart"
RenderTransformOrigin="0.5,0.5"
Width="16"
Height="16"
Visibility="Collapsed"
IsHitTestVisible="False">
<Image.RenderTransform>
<RotateTransform />
</Image.RenderTransform>
</Image>
这篇关于使用VisualStateManager启动和停止故事板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!