在WPF窗口的构造函数中,InitializeComponent()前面应该放什么,后面应该放什么?

在WPF窗口的构造函数中,InitializeComponent()前面应该放什么,后面应该放什么?,wpf,coding-style,Wpf,Coding Style,一般来说,我在初始化InitializeComponent()之前一直在初始化窗口本身的属性,并在之后设置其中包含的控件。然而,我并没有那个么始终如一,我也并没有真正注意到订购的问题。因此: 我(可能)正在做一些可怕的事情吗?特别是,在初始化组件()之前设置子控件的属性是否有任何问题 这方面的好风格是什么 编辑:因为我得到的前两个答案有点矛盾,让我更具体一点: public Foo Foo {get; protected set} public FooWindow (Foo foo) {

一般来说,我在初始化
InitializeComponent()
之前一直在初始化
窗口本身的属性,并在之后设置其中包含的控件。然而,我并没有那个么始终如一,我也并没有真正注意到订购的问题。因此:

  • 我(可能)正在做一些可怕的事情吗?特别是,在初始化组件()之前设置子控件的属性是否有任何问题
  • 这方面的好风格是什么
编辑:因为我得到的前两个答案有点矛盾,让我更具体一点:

public Foo Foo {get; protected set}
public FooWindow (Foo foo)
{
    Foo = foo;
    this.Closing += FooWindow_Closing;
    Foo.Frobbed += Foo_Frobbed;

    InitializeComponent();

    this.DataContext = this;
    this.Title = Foo.Name() + " Window";

    FooListView.ItemSource = Foo.CalculateList();

    FocusManager.SetFocusedElement(this, FooListView);
}

这是对的吗?我是否应该只做MVVM,而在
窗口中没有任何内容
构造函数?

在其他代码之后调用InitializeComponents,可能会意外地用XAML中设置的内容覆盖属性,或者使用未初始化的对象。通常,隐藏的代码的优先级高于XAML,因此我会将InitializeComponent(也称为解析并加载XAML)放在顶部。

我通常在调用InitializeComponent()之前调用不需要可视化树的任何内容。

我的所有实现都使用MVVM模式,因此我更喜欢在将UI加载到客户端之前实例化和填充ViewModel


如果总是先加载InitializeComponent(),则会显示一个突然更新的未填充视图,而不是一个进入视图时填充的视图,从而有可能造成糟糕的用户体验。

在回答您的具体问题时:

我(可能)正在做一些可怕的事情吗?特别是,在初始化Component()之前设置子控件的属性是否有任何问题

在调用InitializeComponents之前,代码中的子控件可能还不可用。这样做通常是不好的

这方面的好风格是什么

这将是一个品味的问题,但通常我会建议,如果您要利用XAML提供的分离,那么我会尽可能地利用它。如果您正在做一些与UI逻辑相关的事情,请尝试在XAML中进行。这与其说是MVVM,不如说是表示与逻辑的分离。示例代码中的大部分内容都可以声明式完成,即使只是通过ValueConverter

例如,如果Foo是dependencProperty,那么您也可以将其附加到XAML中,并将回调添加为ValueChanged回调的一部分。同样,这不是MVVM,但它对WPF来说是非常基本的

对于大多数其他事情,您实际上可能希望等到onload被调用,而不是在构造函数中进行工作


希望有帮助,

这真的是个问题吗?我的意思是,在调用
Window.Show()
之前,用户无法看到控件,而在构造函数完全退出之前,这是不会发生的。我想对于
UserControl
来说,这可能是一个更大的问题,但即使如此,对象在分配时也应该完全构建。我开始相信第一部分,但是否存在多次调用onload的问题(如中所述)?每当加载控件时都会调用onload,这是挂接事件等的适当时间。您还需要在OnUnloaded中解开它们。如果这是一个窗口,那么您真的不应该看到多次调用OnLoaded,但对于控件来说,这是一件需要特别小心的事情(链接的问题指的是经常加载/卸载的页面)。感谢您提供的信息性答案。(很抱歉,我只能接受一个答案,另一个先来。)需要注意的是,如果使用MVVM,则应在调用InitializeComponent()之前设置DataContext,否则将无法正确设置ViewModel绑定。InitializeComponent()调用所有属性绑定getter,因此如果先调用它,则在对每个属性再次调用NotifyPropertyChanged之前,绑定将无法获得正确的值。这一原理同样适用于可能影响xaml初始化方式的任何其他初始化逻辑。