淡出一个窗口

21

我目前正在开发一个WPF C#应用程序。 我已经在窗体的XAML中添加了两个事件触发器,使其在窗口加载时淡入并在窗口关闭时淡出。

淡入效果完美无误,没有任何问题,但淡出效果不起作用。

我的设置是,窗口在加载时淡入,持续5秒钟的计时器后调用表单淡出事件。

然而,窗口并没有淡出,它立即关闭,没有动画效果。以下是我为淡入和淡出事件编写的代码:

<Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard Name="FormFade">
                    <DoubleAnimation Name="FormFadeAnimation"
                                     Storyboard.TargetProperty="(Window.Opacity)"
                                     From="0.0" To="1.0" Duration="0:0:1"
                                     AutoReverse="False" RepeatBehavior="1x" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="Window.Unloaded">
            <BeginStoryboard>
                <Storyboard Name="FormFadeOut" Completed="FormFadeOut_Completed">
                    <DoubleAnimation Name="FormFadeOutAnimation"
                                     Storyboard.TargetName="FormFadeOut"
                                     Storyboard.TargetProperty="(Window.Opacity)"
                                     From="1.0" To="0.0" Duration="0:0:1"
                                     AutoReverse="False" RepeatBehavior="1x" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>

感谢您能提供的任何帮助。


可能是Fading out a wpf window on close的重复问题。 - H.B.
仅供参考:分层窗口(WindowStyle=None, AllowsTransparency=True, Background=Transparent)可以在Windows Vista或更高版本上进行硬件渲染,并且在淡出时避免黑色矩形。 - AlexO
3个回答

40

Unloaded不是一个适合此情况的事件,我不确定这个事件是否甚至可以在Windows上发生。你需要处理Closing事件,防止它实际关闭,开始动画并在动画的Completed事件发生时关闭它。

例如:

<Window ...
        Closing="Window_Closing">
private void Window_Closing(object sender, CancelEventArgs e)
{
    Closing -= Window_Closing;
    e.Cancel = true;
    var anim = new DoubleAnimation(0, (Duration)TimeSpan.FromSeconds(1));
    anim.Completed += (s, _) => this.Close();
    this.BeginAnimation(UIElement.OpacityProperty, anim);
}

你能看到代码吗?这根本不在EventTriggers里面。 - H.B.
在哪里定义Double Animation? - Chris
@Chris:我不明白你的问题。 - H.B.
解决了我的问题。DoubleAnimation 定义在 System.Windows.Media.Animation.DoubleAnimation 中。 - Chris
1
@TravisTubbs:你可以在打开窗口之前/默认情况下将不透明度设置为0,然后以类似的方式在“Loaded”中启动动画。 - H.B.
显示剩余4条评论

6

只需尝试此示例

<Window x:Class="FadeInAndOutWindow.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" Closing="Window_Closing" x:Name="winHelp">
<Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
        <BeginStoryboard>
            <Storyboard Name="FormFade">
                <DoubleAnimation  Name="FormFadeAnimation"
                                  Storyboard.TargetName="winHelp"
                                  Storyboard.TargetProperty="(Window.Opacity)"
                                  From="0.0"
                                  To="1.0"
                                  Duration="0:0:1"
                                  AutoReverse="False"
                                  RepeatBehavior="1x" />
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
    <EventTrigger RoutedEvent="Window.Unloaded">
        <BeginStoryboard>
            <Storyboard Name="FormFadeOut"
                        Completed="FormFadeOut_Completed">
                <DoubleAnimation  Name="FormFadeOutAnimation"
                                  Storyboard.TargetName="winHelp"
                                  Storyboard.TargetProperty="(Window.Opacity)"
                                  From="1.0"
                                  To="0.0"
                                  Duration="0:0:1"
                                  AutoReverse="False"
                                  RepeatBehavior="1x" />
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</Window.Triggers>    
<Grid>

</Grid>

namespace FadeInAndOutWindow
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private bool closeCompleted = false;


        private void FormFadeOut_Completed(object sender, EventArgs e)
        {
            closeCompleted = true;
            this.Close();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {

            if (!closeCompleted)
            {
                FormFadeOut.Begin();
                e.Cancel = true;
            }
        }

    }
}

5

H.B.的解决方案不错,但不能有效地关闭窗口,因为Close()会调用window_Closing并循环。这是我的可行解决方案:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        AlreadyFaded = false;
    }

    bool AlreadyFaded;
    private void window_Closing(object sender, CancelEventArgs e)
    {
        if (!AlreadyFaded)
        {
            AlreadyFaded = true;
            e.Cancel = true;
            var anim = new DoubleAnimation(0, (Duration)TimeSpan.FromSeconds(1));
            anim.Completed += new EventHandler(anim_Completed);
            this.BeginAnimation(UIElement.OpacityProperty, anim);
        }
    }

    void anim_Completed(object sender, EventArgs e)
    {
         Close();
    }

这个解决方案非常好。我创建了一个 BaseWindow 类,所有的窗口都继承它。现在我的所有窗口都有了这种行为。感谢您提供的此改进版本。 - Alexandru Dicu
工作得很好,但是在淡出时会显示一个黑色矩形..有什么想法吗? - Mittchel
1
对话框必须具有AllowsTransparency="True"属性,以避免出现黑色矩形。 - Kemal Taşkın

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接