我想知道在启动WPF应用程序时控件的初始化过程中究竟发生了什么?
DP什么时候会被初始化?绑定时? DataContext何时设置? DataContext是否在控件的构造函数中?有什么样的订单吗?
我意识到我遇到了一个陷阱,一旦我在控件的DP构造函数的getter / setter上设置了值,DP值就会更新,但是值也会立即回滚到默认值null。
所以我的猜测是,构造函数首先被初始化,然后是依赖属性。
有人可以帮我解决这个问题吗?
编辑:只是为了瑞秋。 dp接收值234并且immedialty回滚为null。我认为它是因为构造函数首先被调用,然后发生dps的初始化,这将dp设置为null,因为null是默认值。我错了吗?控制或依赖对象的初始化步骤的顺序是什么。
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));
}
答案 0 :(得分:1)
我发现DispatcherPriority Enum对于回忆确切的事件顺序很有用:
如您所见,构造函数首先运行,然后是数据绑定。
DependencyProperties
在创建对象时初始化,就像任何其他属性一样,因此在构造函数运行之前会发生,因此属性存在于构造函数中。
设置DataContext
属性或其他DependencyProperties
与您正在设置的任何其他属性一样。如果使用绑定设置它们,它们将在构造函数之后得到评估。如果在XAML中设置它们,它们将在构造函数中设置。如果在Loaded事件中设置它们,它们将在构造,绑定和渲染所有内容后设置。
您也可能会发现this SO answer有用:
创建并显示Window时的事件序列
根据要求,这是WPF中的主要事件序列 窗口已创建并显示:
在创建对象时调用构造函数和getter / setter,包括PropertyChangedCallback,ValidationCallback等 正在更新的对象以及从中继承的任何对象
当每个元素被添加到可视或逻辑树时,会触发其初始化事件,这会导致样式和触发器成为 发现应用除了任何特定于元素的初始化你 可以定义[注意:逻辑中的叶子不会触发初始化事件 树,如果根源没有PresentationSource(例如Window)
窗口和所有未折叠的Visuals都是Measured,这会导致每个Control上的ApplyTemplate,这会导致额外的 对象树构造包括更多构造函数和 getter / setter方法
窗口及其上所有未折叠的视觉效果都是“已安排”
窗口及其后代(逻辑和可视)接收Loaded事件
重试首次设置失败的任何数据绑定
- 醇>
窗口及其后代有机会直观地呈现其内容
创建Window时完成步骤1-2,无论是否为 所示。其他步骤通常直到Window才会发生 显示,但如果手动触发,它们可以更早发生。
根据添加到问题的代码进行修改
您的DependencyProperty.Register
方法对我来说很有趣。该方法的签名与该方法的任何overloads都不匹配,并且您正在使用看似自定义的UIProperty
类来设置默认值而不是正常{{3} }}
我可以确认,如果您的代码按正常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>
答案 1 :(得分:0)
在WPF中,您使用PropertyMetaData设置DP的默认值,而不是通过构造函数。
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"));
}