为了在混沌控制初始化步骤(Order In Chaos Of Control Initializat

2019-09-01 03:06发布

我想的控制initalization过程中发生了什么,当我开始一个WPF应用程序知道真正是什么时候?

当DP initalized? 当绑定? 什么时候得到的DataContext设置? 在控制的构造函数的DataContext avaialbe? 有什么样的顺序?

我意识到,我遇到了,一旦我在一个DP的的getter / setter设定值内控制了DP值被更新的构造函数,但立即又值被回滚到这是空默认值的陷阱。

所以我的猜测是,contructors获得第一initalized再依赖属性。

有人可以帮我这个?

编辑:只是为了雷切尔。 在DP接收数值234和immedialty回滚到零。 我认为它是因为构造函数被调用第一和随后的dps initalizing是因为null是默认值设置DP回零。 我在想错了吗? 什么是控制或依赖对象的initalization步骤的顺序。

class MySuperDuperCoolClass : ContentControl
{
  public MySuperDuperCoolClass()
  {
    InitalizeComponents();
    this.MySuperDuperProperty = "234";
  }

  public string MySuperDuperProperty
  {
    get { return (string)GetValue(MySuperDuperPropertyProperty);}
    set { SetValue(MySuperDuperPropertyProperty, value);}
  }

  public static DependencyProperty MySuperDuperPropertyProperty =
    DependencyProperty.Register("MySuperDuperProperty", typeof(string), typeof(MySuperDuperCoolClass), 
    new PropertyMetadata(null));

}

Answer 1:

我找到的DispatcherPriority枚举的召回确切的事件顺序有用:

  • 发送
  • 正常 -构造跑这里来了
  • 的DataBind
  • 给予
  • 加载
  • 背景
  • ContextIdle
  • ApplicationIdle
  • SystemIdle
  • 待用
  • 无效
  • 输入

正如你可以看到,构造函数会首先运行,其次是数据绑定。

DependencyProperties当对象被创建,就像任何其他财产得到初始化,这样就会出现被运行前的构造函数,因此该属性在构造函数中存在。

设置DataContext财物或者其他DependencyProperties作品就像您设置任何其他财产。 如果你有一个绑定设置他们,他们会得到构造后评估。 如果您在XAML设置它们,它们将在构造函数置位。 如果您在加载事件中设置他们,他们会得到一切设置已建成之后,势必,和渲染。

你也可能会发现这个苏答案有用:

事件序列被创建并显示一个窗口时

按照要求,这里是WPF重大事件时创建并显示一个窗口的序列:

  1. 构造函数和getter / setter方法被称为创建对象,包括PropertyChangedCallback,ValidationCallback等上正在更新的对象,并从他们继承的任何对象

  2. 由于每个元素被添加到视觉或逻辑树的Intialized事件被激发,这将导致样式和触发器被发现除了你可以定义[注任何特定元素初始化应用:在逻辑树不解雇叶初始化事件如果没有PresentationSource(例如窗口)在其根部]

  3. 窗口并在其上所有的非折叠的视觉效果被测量,这会导致在每个控制,这会导致附加的对象树结构,其包括多个构造和getter / setter方法的ApplyTemplate在

  4. 该窗口上的所有未塌缩的视觉效果被安排

  5. 窗口及其后代(逻辑和视觉)接收加载事件

  6. 当他们失败的第一组的任何数据绑定试

  7. 该窗口及其后代有机会直观地呈现其内容

步骤1-2是在创建窗口时完成的,无论它是否被示出。 至于其他的步骤一般不会发生,直到所示的窗口,但如果手动触发他们可以更早发生。

基于代码编辑加入到质疑

DependencyProperty.Register方法看起来很滑稽我。 该方法的签名不匹配任何的重载该方法,而你使用的是什么似乎是一个自定义UIProperty类设置的默认值,而不是正常PropertyMetadata 。

我可以肯定,如果你的代码运行与正常预期DependencyProperty.Register签名,所以你的问题的可能的原因是无论是在您的自定义代码的某个地方,或者你是如何使用/设置属性的。

我用一个快速的样本测试的代码是这样的:

public partial class UserControl1 : ContentControl
{
    public UserControl1()
    {
        InitializeComponent();
        this.TestDependencyProperty = "234";
    }

    public string TestDependencyProperty
    {
        get { return (string)GetValue(TestDependencyPropertyProperty); }
        set { SetValue(TestDependencyPropertyProperty, value); }
    }

    public static DependencyProperty TestDependencyPropertyProperty =
        DependencyProperty.Register("TestDependencyProperty", typeof(string), typeof(UserControl1), 
        new PropertyMetadata(null));
}

而XAML是

<ContentControl x:Class="WpfApplication1.UserControl1"
                x:Name="TestPanel" ...>
    <Label Content="{Binding ElementName=TestPanel, Path=TestDependencyProperty}"/>
</ContentControl>


Answer 2:

在WPF您是DP与PropertyMetaData不是通过构造函数设置的默认值。

public partial class UserControl1 : ContentControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    public string TestDependencyProperty
    {
        get { return (string)GetValue(TestDependencyPropertyProperty); }
        set { SetValue(TestDependencyPropertyProperty, value); }
    }

    public static DependencyProperty TestDependencyPropertyProperty =
        DependencyProperty.Register("TestDependencyProperty", typeof(string), typeof(UserControl1), 
        new PropertyMetadata("234"));
}


文章来源: Order In Chaos Of Control Initialization Steps