使用VisualStateManager启动和停止故事板 [英] Using VisualStateManager to start and stop Storyboards

查看:246
本文介绍了使用VisualStateManager启动和停止故事板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,它通过将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



您可以做这样的事情:




  1. 使用扩展模板控制 ContentControl中
    IsEnabled 的含量(防止等待时的动作的);

  2. 创建一个DP IsWaiting 的切换你的控制可视状态;

  3. 创建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}
Horizo​​ntalContentAlignment ={TemplateBinding Horizo​​ntalContentAlignment}
VerticalContentAlignment ={TemplateBinding VerticalContentAlignment}
前景={TemplateBinding前景}
ScrollViewer.Horizo​​ntalScrollBarVisibility ={TemplateBinding ScrollViewer.Horizo​​ntalScrollBarVisibility }
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 :

  1. Use a template control that extend ContentControl to play with IsEnabled of content (prevent action during waiting) ;
  2. Create a DP IsWaiting that switch your control visual state ;
  3. Create the two states in XAML : Use DoubleAnimation with RepeatBehavior="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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆