如何在Silverlight 4中等待状态转换完成?

我需要更改控件的状态然后执行一些操作。 具体来说,我想在隐藏控件之前运行动画。 我想做那样的事情:

VisualStateManager.GoToState(control, "Hidden", true); // wait until the transition animation is finished ParentControl.Children.Remove(control); 

问题是过渡动画是异步运行的,因此在动画启动后立即从可视树中删除控件。

那么我该如何等待动画完成呢?

您可以将Storyboard.Completed事件处理程序附加到Storyboard,或将VisualStateGroup.CurrentStateChanged事件处理程序附加到VisualStateGroup:

              

 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) { } } 

}

处理此问题的正确方法是在VisualStateGroup上侦听CurrentStateChanged事件,但根据我的经验,它最多不可靠并且在最坏情况下会被破坏。

第二个选项是在Storyboard上挂钩Completed事件,但是这个选项有自己的缺陷。 在某些情况下,可视状态管理器会在内部生成动画,因此您设置的已完成事件将不会被调用。

实际上可以在代码中附加Completed处理程序:

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

此主题的示例: http : //forums.silverlight.net/forums/p/38027/276746.aspx

在使用附加行为的实时项目中为我工作! 虽然我不得不为根UserControl(在VisualStateManager.GoToState中使用)和LayoutRoot使用单独的依赖属性来获取实际的VisualStateGroup集合,但有点烦人。