了解WPF窗口事件

时间:2016-06-22 17:17:10

标签: c# wpf events

我看到Windows有Loaded个事件,但没有Loading个事件(因为有ClosingClosed个事件。

我的期望是Loaded事件会在实际显示窗口之前发生。但是,查看Window Lifetime Events,表明Loaded事件发生在Activated事件之后。

我在Loaded事件中放了一些初始化代码,在显示窗口之后和我的内容出现之前有一段延迟。那么在窗口显示之前应该用于窗口初始化的最佳事件处理程序是什么?

3 个答案:

答案 0 :(得分:18)

如本codeproject文章所述:

这是WPF的完整生命周期

启动:(应用程序)

这是应用程序被解雇的第一个生命事件。在主窗口上调用Application.Run()时会触发此操作。但是在显示主窗口之前。请注意,Application.Run()是从用户中抽象出来的。如果要检查编译器生成的代码,请在projec \ obj文件夹下搜索名为App.g.i.cs的文件(g代表生成的)。

这是您可以处理应用程序收到的任何命令行参数的事件。

已初始化:(窗口)

这是被触发的窗口的第一个终身事件。这是一个普通的.Net事件,而不是路由事件。当在窗口级别触发此事件时,这意味着它的所有嵌套子控件也已初始化。因此,子控件将触发Initialized事件,然后是父控件,最后是Window。 一旦窗口被实例化,就会发生这种情况。此事件位于基类FrameworkElement的级别。请注意,此级别不会应用样式和数据绑定。一个有趣的事情是FrameworkElement为Animation,styles和DataBinding定义服务。

SourceInitialized :(窗口)

获取适合您窗口的传统句柄。但是你的窗户仍然不可见。

已激活:(应用程序)

每当此应用程序的窗口出现在前景时以及第一次呈现应用程序窗口时调用。请注意,只有在此事件窗口的激活事件被触发后才真正有意义

已激活:(窗口)

相当于控件的GotFocus。每次窗口到达前景时调用,也是第一次渲染窗口时调用。仅在此事件窗口加载事件被触发后。

已加载:(窗口)

整个窗口准备就绪。渲染前的最后一站。所有动画,样式和数据绑定都将在此处准备就绪。任何视觉调整都需要在这里完成。

ContentRendered :(窗口)

顾名思义,它是在呈现内容后发生的。如果没有内容,则根本不会触发此事件。不要在这里做任何视觉调整。从这里开始,您可以为您的业务逻辑设置一个标志,该窗口已启动,运行并首次显示给用户。

关闭事件顺序:

结束:(窗口)

触发器可以是用户操作或编程。用户操作可以像点击关闭按钮一样直接。

停用:(窗口)

如果窗口失去焦点(这是与control.GotFocus()等效的窗口)或关闭,则会发生。

停用:(应用程序)

如果用户切换到另一个应用程序(通过Alt-Tab,任务栏或任务管理器等)或应用程序关闭的影响,则会发生错误。

已关闭:(窗口)

窗口已关闭,但可以访问窗口元素。如果有原因,最后访问它们的地方。请注意,此窗口被卸载后将被触发。

退出:(申请)

最后但并非最不重要。只返回Run()方法。 (请参阅上面的启动事件,了解Run()方法的注释)。但是如果你已经编写了自定义的main()方法而不是生成的方法,那么你可以在这里添加一些业务逻辑代码。任何快速资源释放都可以在这里完成。

答案 1 :(得分:1)

您可以在App.xaml.cs中覆盖OnStartup(),并在调用base.OnStartup(e);之前执行操作。我刚刚检查了一下,并在窗口的构造函数之前将其触发。

或者,在其xaml文件中将窗口的可见性设置为Hidden,在构造函数中进行初始化,然后在完成后将可见性设置为Visible。这不会消除延迟,但是延迟仅由初始化代码正在执行的操作引起,因此除非您进行异步操作,否则这是不可避免的。

答案 2 :(得分:0)

这是我的工作的简化版本(已删除错误处理)。如果初始化需要一段时间,则可能需要在执行操作时显示初始屏幕。

App.xaml:

<Application x:Class="MyProgram.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Startup="App_StartUp" >
</Application>

App.xaml.cs:

namespace MyProgram
{
    public partial class App : Application
    {
        private void App_StartUp(object sender, StartupEventArgs e)
        {
            // Create the model and MainWindow
            MyModel model = CreateModel();
            MainViewModel viewModel = new MainViewModel(model);
            MainWindow = new MainWindow(viewModel); // Sets the DataContext

            // Do things, like initialize your model
            model.Initialize();

            // Now show your window
            MainWindow.Show();
        }
    }
}