代码之家  ›  专栏  ›  技术社区  ›  gius

如何在Silverlight4中等待状态更改转换完成?

  •  12
  • gius  · 技术社区  · 14 年前

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

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

    3 回复  |  直到 14 年前
        1
  •  14
  •   Michael S. Scherotter    14 年前

    您可以附加情节提要。已完成事件处理程序或附加VisualStateGroup.CurrentStateChangedVisualStateGroup的事件处理程序:

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

        2
  •  3
  •   Denis    14 年前

    处理此问题的正确方法是在VisualStateGroup上侦听CurrentStateChanged事件,但根据我的经验,它最好是不可靠的,最坏是坏的。

        3
  •  3
  •   dain    14 年前

    实际上,可以在代码中附加已完成的处理程序:

    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;
            }
        }
    }
    

    此线程的示例: http://forums.silverlight.net/forums/p/38027/276746.aspx

    为我工作的生活项目使用附加行为太!虽然有点恼人,但是我必须为根用户控件使用单独的依赖属性(在VisualStateManager.GoToState)以及LayoutRoot以获取实际的VisualStateGroup集合。