InitializeComponent()是什么,它在WPF中如何工作?

183

InitializeComponent() 在 WPF 中是做什么的,它是如何工作的?

总的来说,当有附加属性时,我尤其想知道构造顺序的详细信息以及会发生什么。


2
谢谢,我认为以下这些都是非常好的答案!虽然没有人特别提到 AttachedProperties,但现在我知道 Xaml 中的任何 AttachedProperties 都只是作为 Xaml 解析的一部分而创建的,所以它们并不需要特别提及。 - Tim Lovell-Smith
2个回答

169

InitializeComponent()方法通常在WindowUserControl的默认构造函数中调用,实际上是对控件的局部类进行方法调用(而不是像我最初预期的那样沿着对象层次结构进行调用)。

此方法定位正在加载的Window/UserControl的XAML的URI,并将其传递给System.Windows.Application.LoadComponent()静态方法。 LoadComponent()加载位于传递的URI处的XAML文件,并将其转换为由XAML文件的根元素指定的对象的实例。

更详细地说,LoadComponent创建了一个XamlParser的实例,并建立了XAML的树形结构。每个节点都由XamlParser.ProcessXamlNode()解析。这个过程被传递到BamlRecordWriter类。在这之后的一段时间里,我有点迷失在BAML如何转换为对象的过程中,但这可能足以帮助您走向启示之路。

注意:有趣的是,InitializeComponentSystem.Windows.Markup.IComponentConnector接口的方法,而Window/UserControl在局部生成的类中实现了该接口。


@Brad,你是怎么找到InitializeComponent接口定义在哪里的?在.xaml.cs文件中,对该接口的F1帮助引导我们到“页面未找到”,而在.g.cs或.g.i.cs文件中,我们则会跳转到Microsoft.SPOT.Emulator.EmulatorComponent类。我对WPF不是很熟悉,这个方法是在编译时生成的吗? - Vimes
没有在构造函数中调用InitializeComponent,控件将无法在其所在的XAML中显示或可用。 - Jason Rae
1
有趣。我原本以为 XAML 只在编译期间使用。那么在运行时拥有 XAML 的意义是什么,它存储在哪里? - Jesper Matthiesen
为什么有些方法会给我一个“对象引用未设置为对象的实例”错误? - Peter Gruppelaar
@JesperMatthiesen 或许是为了热重载?这样在调试期间,对 XAML 的更改会在运行时反映出来,而无需重新启动/重新编译应用程序。 - Michael Schnerring

27

阅读代码也是有帮助的。也就是说,您可以通过以下步骤查看生成的部分类(调用LoadComponent):

  1. 转到您感兴趣的Visual Studio解决方案中的“解决方案资源管理器”窗格。
  2. "显示所有文件"按钮在“解决方案资源管理器”的工具栏中。切换该按钮。
  3. 现在,展开obj文件夹,然后展开DebugRelease文件夹(或任何您正在构建的配置),你会看到一个名为 YourClass.g.cs 的文件。

YourClass.g.cs ...是生成的部分类的代码。同样,如果您打开它,您可以看到InitializeComponent方法及其如何调用LoadComponent...以及更多内容。


12
请注意,您可以通过在构造函数中右键单击方法调用并选择“转到定义”来一步完成此操作。 - Brad Leach
2
啊,没错...忘了那个。这样做容易多了。好吧,至少你知道它是如何包含在项目中的。咧嘴笑。 - cplotts
1
@Brad Leach,晚到了这个派对,你可以使用F12完成它。 - Julius Depulla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接