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

发布于 2024-09-17 21:22:18 字数 292 浏览 5 评论 0原文

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

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

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

那么如何等待动画结束呢?

I need to change state of a control and then do some action. To be specific, I want to run an animation before a control is hidden. I would like to do something like that:

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

The problem is that the transition animation is run asynchronously and thus the control is removed from the visual tree right after the animation is started.

So how do I wait for the animation to finish?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

匿名。 2024-09-24 21:22:18

您可以将 Storyboard.Completed 事件处理程序附加到 Storyboard 或将 VisualStateGroup.CurrentStateChanged 事件处理程序附加到 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)
    {

    }
}

}

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

    }
}

}

新人笑 2024-09-24 21:22:18

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

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

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

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.

柠檬色的秋千 2024-09-24 21:22:18

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

第二种选择是将已完成事件挂接到故事板上,但此选项有其自身的陷阱。在某些情况下,视觉状态管理器会在内部生成动画,因此您设置的 Completed 事件将不会被调用。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文