我想的控制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));
}
我找到的DispatcherPriority枚举的召回确切的事件顺序有用:
- 发送
- 正常 -构造跑这里来了
- 的DataBind
- 给予
- 加载
- 背景
- ContextIdle
- ApplicationIdle
- SystemIdle
- 待用
- 无效
- 输入
正如你可以看到,构造函数会首先运行,其次是数据绑定。
DependencyProperties
当对象被创建,就像任何其他财产得到初始化,这样就会出现被运行前的构造函数,因此该属性在构造函数中存在。
设置DataContext
财物或者其他DependencyProperties
作品就像您设置任何其他财产。 如果你有一个绑定设置他们,他们会得到构造后评估。 如果您在XAML设置它们,它们将在构造函数置位。 如果您在加载事件中设置他们,他们会得到一切设置已建成之后,势必,和渲染。
你也可能会发现这个苏答案有用:
事件序列被创建并显示一个窗口时
按照要求,这里是WPF重大事件时创建并显示一个窗口的序列:
构造函数和getter / setter方法被称为创建对象,包括PropertyChangedCallback,ValidationCallback等上正在更新的对象,并从他们继承的任何对象
由于每个元素被添加到视觉或逻辑树的Intialized事件被激发,这将导致样式和触发器被发现除了你可以定义[注任何特定元素初始化应用:在逻辑树不解雇叶初始化事件如果没有PresentationSource(例如窗口)在其根部]
窗口并在其上所有的非折叠的视觉效果被测量,这会导致在每个控制,这会导致附加的对象树结构,其包括多个构造和getter / setter方法的ApplyTemplate在
该窗口上的所有未塌缩的视觉效果被安排
窗口及其后代(逻辑和视觉)接收加载事件
当他们失败的第一组的任何数据绑定试
该窗口及其后代有机会直观地呈现其内容
步骤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>
在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"));
}