在InitializeComponent期间WPF获取控件空引用

所以我在Window的构造函数中的InitializeComponent方法调用正在运行XML并添加控件并将它们插入到它们的事件中。

因此,当其中一个控件的属性发生更改时,它会调用订阅该事件的Method。 该方法引用尚未构建的控件。

为什么这会按此顺序发生? 它在WinForms中有效,因为在创建所有控件之后,事件才会被激活。 有没有办法在WPF中强制执行此操作?

我看到的其他解决方案是

  • 我需要在初始化后订阅事件。

  • 每当我处理一个控件时,我都需要检查null。

我也遇到了这个问题,并通过在null检查中包含访问空控件的行来解决它。 这似乎是一个黑客的解决方法。

我认为WPF通过在InitializeComponent()期间调用Checked事件来尝试提供帮助,以确保根据复选框的初始状态执行任何UI逻辑(例如显示/隐藏相关组件)。 我测试默认情况下取消选中Checkbox,并且未调用事件处理程序,即使我将它连接到Checked和Unchecked事件。 我甚至在一个空白的WPF项目中重现了这一点,屏幕上有一个Checkbox,它的行为相同。

此默认行为的问题显然是某些其他组件尚未初始化。 我认为WPF应该等到所有组件都被初始化,然后默认触发Checked事件。 这可能不会被视为错误,但无论如何我都要在相关的MSDN页面添加注释…

这是在radiobutton上的Checked事件。 当我从xaml中删除Checked =“true”时,问题就消失了。 (虽然在Window启动时检查)。 不确定这里发生了什么,但至少我没有必要改变任何重要的东西来修复它……

您应该能够检查窗口上的IsInitialized或IsLoaded属性,以validation它是否已完成初始化/加载。 否则,您需要检查null或在后面的代码中添加事件订阅(在InitializeComponent之后)。

此外,您可以调整访问元素的方式。 例如,如果你有类似的东西:

  

然后在您的代码中,您可以通过以下几种方式获取列表框:

 private void OnListBoxSelectionChanged(object sender, SelectionChangedEventArgs e) { ListBox lb = this.listBox; // May be null ListBox lb = sender as ListBox; // Should never be null ListBox lb = e.Source as ListBox; // Same as sender in this case ListBox lb = e.OriginalSource as ListBox; // Always the element that started the event (if handler is not attached directly to ListBox). // ... Do Something ... } 

我有同样的问题,我认为这是一个错误。 我发现了一个解决方法:我从Xaml中删除了’Ischecked’并在init之后将其设置在后面的代码中

是否有任何控件使用双向数据绑定? 我遇到过这个问题,我将文本框绑定到ViewModel上的属性。 ViewModel初始化触发INotifyPropertyChanged直到绑定控件,这反过来导致文本框的TextChanged事件触发。 我的短期解决方法是将事件订阅移动到Loaded事件窗口,但是就像你说的那样,这是一种痛苦。 我需要重构代码以更改我的对象初始化的顺序,以便在ViewModel之前创建WPF视图(即窗口和用户控件)。 然后我将能够将事件处理程序注册移回XAML。

窗口控件在初始化可以检查并设置为检查为初始值的子控件时触发已检查事件。

我强烈认为这是一个错误。 事实上,它从MFC程序集中深处触发NullReferenceException应该足以预期这是非预期的行为。

考虑到Xaml编辑器在Control部分类中创建处理函数,如果这个类没有完成构造,则它无法处理事件。 我不认为为控件启动一个已检查的事件,你的设置初始化为检查似乎是正确的。

我的意思是,如果您将其初始状态设置为未选中,是否应该触发未经检查的事件?