【问题标题】:Fading out a window淡出一扇窗
【发布时间】:2011-08-22 22:39:59
【问题描述】:

我目前正在开发一个 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>

感谢您提供的任何帮助。

【问题讨论】:

  • 只是上面的注释:分层 Windows (WindowStyle=None, AllowsTransparency=True, Background=Transparent) 可以在 Windows Vista 或更高版本上进行硬件渲染,并且在其淡出时将避免黑色矩形。

标签: c# wpf xaml animation window


【解决方案1】:

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

【讨论】:

  • 我已经尝试了你的建议,现在出现了一个异常,说'Window.Closing value cannot be assigned to property'RoutedEvent of object System.Windows.EventTrigger
  • 你能看到代码吗?这根本不是在 EventTriggers 内。
  • 对不起,我看错了你的代码,完美运行,感谢您的帮助
  • 不客气,但下次请多注意 SO,因为这个问题有重复,应该不难找到。
  • @TravisTubbs:您可能可以在打开窗口/默认情况下将不透明度设置为 0,然后以类似的方式在 Loaded 中启动动画。
【解决方案2】:

试试这个示例

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

    }
}

【讨论】:

    【解决方案3】:

    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 类,我所有的窗口都继承自它。我所有的窗户现在都有这种行为。感谢您提供这个改进的版本。
    • 效果很好,但由于某种原因,它在淡出时显示为黑色矩形......对此有什么想法吗?
    • 对话框必须具有 AllowsTransparency="True" 属性以避免出现黑色矩形。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 2019-05-02
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多