Window.Loaded和Window.ContentRendered事件有什么区别

WPF中的Window.LoadedWindow.ContentRendered事件有什么区别? 首先调用ContentRendered事件?

这里说的Window.ContentRendered事件的描述

在窗口内容被渲染后发生。

这里的Window.Loaded事件的描述说

当元素布局,呈现并准备好进行交互时发生。

我有一个情况,我想将窗口的MaxHeight设置为正在显示我的窗口的屏幕的工作区域的高度。 我应该做哪个事件?

编辑:

我想我find了我正在寻找的东西,但现在我更加困惑了。 Loaded事件首先发生,然后发生ContentRendered事件。 在Chris Sells&Ian Griffiths编写WPF的书中,它说Loaded事件是

在窗口显示之前引发

而“ContentRendered”事件是

当窗口的内容被可视化渲染时引发。

这与MSDN文档中有关Loaded事件的内容相矛盾:

当元素布局,呈现并准备好进行交互时发生。

这现在更令人困惑。

我认为这两个事件没什么区别。 为了理解这一点,我创build了一个简单的例子来操纵:

XAML

 <Window x:Class="LoadedAndContentRendered.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="MyWindow" Title="MainWindow" Height="1000" Width="525" WindowStartupLocation="CenterScreen" ContentRendered="Window_ContentRendered" Loaded="Window_Loaded"> <Grid Name="RootGrid"> </Grid> </Window> 

Code behind

 private void Window_ContentRendered(object sender, EventArgs e) { MessageBox.Show("ContentRendered"); } private void Window_Loaded(object sender, RoutedEventArgs e) { MessageBox.Show("Loaded"); } 

在这种情况下, Loaded消息在ContentRendered消息之后出现。 这确认了文档中的信息。

一般来说,在WPF中, Loaded事件会触发元素:

被布置,呈现并准备好进行交互。

由于在WPF中Window是相同的元素,但是它通常应该被放置在根面板中的内容(例如: Grid )。 因此,监视Window的内容并创build一个ContentRendered事件。 来自MSDN的评论:

如果窗口没有内容,则不会引发此事件。

也就是说,如果我们创build一个Window

 <Window x:Class="LoadedAndContentRendered.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="MyWindow" ContentRendered="Window_ContentRendered" Loaded="Window_Loaded" /> 

它只会运行Loaded事件。

关于访问Window的元素,它们以相同的方式工作。 我们在WindowGrid中创build一个Label 。 在这两种情况下,我们已经成功接收到Width

 private void Window_ContentRendered(object sender, EventArgs e) { MessageBox.Show("ContentRendered: " + SampleLabel.Width.ToString()); } private void Window_Loaded(object sender, RoutedEventArgs e) { MessageBox.Show("Loaded: " + SampleLabel.Width.ToString()); } 

至于StylesTemplates ,在这个阶段,它们被成功应用,在这些事件中,我们将能够访问它们。

例如,我们要添加一个Button

 private void Window_ContentRendered(object sender, EventArgs e) { MessageBox.Show("ContentRendered: " + SampleLabel.Width.ToString()); Button b1 = new Button(); b1.Content = "ContentRendered Button"; RootGrid.Children.Add(b1); b1.Height = 25; b1.Width = 200; b1.HorizontalAlignment = HorizontalAlignment.Right; } private void Window_Loaded(object sender, RoutedEventArgs e) { MessageBox.Show("Loaded: " + SampleLabel.Width.ToString()); Button b1 = new Button(); b1.Content = "Loaded Button"; RootGrid.Children.Add(b1); b1.Height = 25; b1.Width = 200; b1.HorizontalAlignment = HorizontalAlignment.Left; } 

Loaded事件的情况下, ButtonWindow出现时立即添加到Grid 。 在ContentRendered事件的情况下, Button添加到Grid后,其所有内容将出现。

因此,如果要在加载Window之前添加项目或更改,则必须使用Loaded事件。 如果要执行与Window内容相关的操作(例如截图),则需要使用ContentRendered事件。

如果您访问此链接https://msdn.microsoft.com/library/ms748948%28v=vs.100%29.aspx#Window_Lifetime_Events并向下滚动到窗口生命周期事件,它会显示您的事件顺序。;

打开:

  1. SourceInitiated
  2. 活性
  3. 加载
  4. ContentRendered

关:

  1. 闭幕
  2. 停用
  3. closures

如果您使用数据绑定,则需要使用ContentRendered事件。

对于下面的代码,在引发Loaded事件时,Header为NULL。 但是,在引发ContentRendered事件时,Header将获取其值。

 <MenuItem Header="{Binding NewGame_Name}" Command="{Binding NewGameCommand}" />