`ContentRendered`与`Loaded`

时间:2014-11-01 10:24:45

标签: wpf

我曾经在调用InitializeComponent之后在构造函数中放置了可见的初始化,尽管我注意到网络上的示例与此不一致:有些人在调用InitializeComponent之前初始化。我最近注意到,即使此类初始化位于ContentRendered事件中,它们仍然会及时显示,即使Windows Lifetime Events文档显示ContentRendered已经很晚了。事实上,这个名字暗示为时已晚:Content Rendered是过去式。以下代码具有预期的行为表明内容在事件发生时尚未真实完整地呈现,并且ContentRendered发生的时间早于名称所示。如果它还相当早,那么就会提出一个问题,即为什么我们需要使用Loaded,这也比完整渲染更早?

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ContentRenderedEvent(object sender, EventArgs e)
        {
            Label1.Content = "This is Label1";
            TextBox1.Text = "hello";
        }
    }

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
               ContentRendered="ContentRenderedEvent">
    <StackPanel>
        <Label x:Name="Label1" Margin="5" 
             Width="100" Height="30">not initialized</Label>
        <TextBox Margin="5" x:Name="TextBox1" Width="60" Height="30"></TextBox>
    </StackPanel>
</Window>

1 个答案:

答案 0 :(得分:1)

即使ContentRendered实际上已经太晚了,您正在初始化的属性(Label.ContentTextBox.Text)也是DependencyProperties。无论何时更改框架都会进行交易,这会强制更新UI。那个(加上绑定)是完全拥有它们的重点,而不是简单的自动道具和简单的get / set对。

所以,当你在ContentRendered中分配它们时,那​​么:

  • 构建UI
  • 用户界面测量并布局
  • 在没有初始化的情况下呈现UI
  • 您正在设置这些属性(渲染后几乎立即)
  • UI获取更新的值(在设置后几乎立即显示)
  • 再次
  • 测量并布置用户界面
  • 你在UI上看到“他们在那里好像没事”

与您在Loaded中执行此操作相比:

  • 构建UI
  • 您正在设置这些属性
  • 用户界面测量并布局
  • 你在UI上看到“他们在那里好像没事”

这是一个粗略的草图,但你应该看到明显的差异。关键点是:

  • 你可能根本没有设法在屏幕上看到非常快速的更新,事实上,WPF可以双重缓冲,v-sync或类似的东西,而中间渲染可能根本就不可见。您可以尝试在ContentRendered事件中捕获视图的某些状态 - 例如,您可以通过编程方式将当前视图另存为PNG,以便能够看到确切的中间状态
  • 请记住DependencyProperties 智能。转到他们的文档(即TextBox.Text) - 并检查他们的标志。如果您看到AffectsRender/Measure/Arrange之类的内容。然后更改它们将触发几乎立即更新/重绘。所有三个标志都很重要。 “内容”类属性(文本,内容,数据源,项目......)几乎总是用AffectsMeasure标记,因为改变内容通常不仅要强制绘画,还要重新制作完整的布局周期每次改变价值观。 “风格”型道具(前景,背景,填充,画笔,......)通常只有AffectsRender,因为重绘足够,布局可以是相同的。等等。 More on that i.e. here on excellent Dr.WPF blog。虽然它是关于Silverlight的,但基础仍然适用。