How to wait for state changing transition to finish in Silverlight 4?

白昼怎懂夜的黑 提交于 2019-12-04 00:38:28

You can attach a Storyboard.Completed event handler to the Storyboard or attach a VisualStateGroup.CurrentStateChanged event handler to the VisualStateGroup:

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
x:Class="SilverlightApplication7.MainPage"
Width="640" Height="480">

<Grid x:Name="LayoutRoot" Background="White">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="VisualStateGroup" >
            <VisualState x:Name="Hidden">
                <Storyboard Completed="OnHidden">
                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Rectangle x:Name="rectangle" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="136" Margin="48,72,0,0" Opacity="0" Stroke="Black" VerticalAlignment="Top" Width="208"/>
</Grid>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightApplication7
{
public partial class MainPage : UserControl
{
    public MainPage()
    {
        // Required to initialize variables
        InitializeComponent();

        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        VisualStateManager.GoToState(this, "Hidden", true);
    }

    private void OnHidden(object storyboard, EventArgs args)
    {

    }
}

}

The correct way of handling this issue would be listening to CurrentStateChanged event on VisualStateGroup, but from my experience it is not reliable at best and broken at worst.

Second option is to hook Completed event on your Storyboard, but this option got pitfalls of its own. In some cases visual state manager generates animations internally, so Completed event you set will not get called.

It is in fact possible to attach the Completed handler in code:

Collection<VisualStateGroup> grps = (Collection<VisualStateGroup>)VisualStateManager.GetVisualStateGroups(this.LayoutRoot);
foreach (VisualStateGroup grp in grps) {
    Collection<VisualState> states = (Collection<VisualState>)grp.States;
    foreach (VisualState state in states) {
        switch (state.Name) {
            case "Intro":
            state.Storyboard.Completed += new EventHandler(Intro_Completed);break;
        }
    }
}

Example from this thread: http://forums.silverlight.net/forums/p/38027/276746.aspx

Working for me in live project using attached Behavior too! Slightly annoying though that I had to use separate dependency properties for the root UserControl (to use in VisualStateManager.GoToState) and the LayoutRoot to get the actual VisualStateGroup collection.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!