简体   繁体   中英

Is Databinding or TemplateBinding supported within the VisualStateManager?

I am trying to delay an animation of a custom control based on a binding value. In the example below, I'd like the animation to start 5 seconds after the “SelectedAndHit” visual state is selected. However, it doesn't seem possible to use template binding within the VisualStateManage.

Is TemplateBinding supported within the VisualStateManager? Is there any workaround?

<local:ButtonEx x:Name="Button01" AnimationBeginTime="00:00:05" />

public TimeSpan AnimationBeginTime
{
    get { return (TimeSpan)base.GetValue(ButtonEx.AnimationBeginTimeProperty); }
    set { base.SetValue(ButtonEx.AnimationBeginTimeProperty, value); }
}

public static readonly DependencyProperty AnimationBeginTimeProperty =
   DependencyProperty.Register("AnimationBeginTime", typeof(TimeSpan), typeof(ButtonEx), new PropertyMetadata(TimeSpan.Zero));

<Style TargetType="local:ButtonEx">
    <!-- ... -->

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:ButtonEx">
                <Grid x:Name="Container" RenderTransformOrigin="0.5, 0.5">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="SelectedAndHit">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border" 
                                                                   Storyboard.TargetProperty="Background">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundColorSelectedAndHit}" />
                                    </ObjectAnimationUsingKeyFrames>

                                    <Storyboard>
                                        <DoubleAnimation
                                            Storyboard.TargetName="GridScaleTransform"
                                            Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
                                            To="1.2" BeginTime="{TemplateBinding AnimationBeginTime}" Duration="00:00:00.300" AutoReverse="True">
                                            <DoubleAnimation.EasingFunction>
                                                <ExponentialEase EasingMode="EaseIn" />
                                            </DoubleAnimation.EasingFunction>
                                        </DoubleAnimation>

                                        <DoubleAnimation
                                            Storyboard.TargetName="GridScaleTransform"
                                            Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
                                            To="1.2" BeginTime="{TemplateBinding AnimationBeginTime}" Duration="00:00:00.300" AutoReverse="True">
                                            <DoubleAnimation.EasingFunction>
                                                <ExponentialEase EasingMode="EaseIn" />
                                            </DoubleAnimation.EasingFunction>
                                       </DoubleAnimation>
                                    </Storyboard>
                                </Storyboard>
                            </VisualState>

                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>

                    <Grid.RenderTransform>
                        <ScaleTransform x:Name="GridScaleTransform" />
                    </Grid.RenderTransform>

                    <!-- ... -->
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I confirm that WinRT doesn't support Binding/TemplateBinding within a style. To workaround the issue I wrote code to manually update the BeginTime of the Storyboard. That way I had full control on when the Storyboard begins.

I would look at Interactivity . I've personally used the EventTrigger with GoToStateAction , which was enough for my purposes. From looking at MSDN it looks like you might be able to make use of TimerTrigger and GoToStateAction to create the effect you're looking for. TimerTrigger has dependency properties for setting the delay of the action to fire.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM