所以我InitializeComponent在Window的构造函数中的方法调用正在运行XML并添加控件并将它们插入到它们的事件中.
因此,当其中一个控件的属性发生更改时,它会调用订阅该事件的Method.该方法引用尚未构建的控件.
为什么这会按此顺序发生?它在WinForms中有效,因为在创建所有控件之后,事件才会被激活.有没有办法在WPF中强制执行此操作?
我看到的其他解决方案是
我需要在初始化后订阅事件.
每当我处理一个控件时,我都需要检查null.
Jor*_*ger 28
我也遇到了这个问题,并通过在null检查中包含访问空控件的行来解决它.这似乎是一个黑客的解决方法.
我认为WPF通过在InitializeComponent()期间调用Checked事件来尝试提供帮助,以确保根据复选框的初始状态执行任何UI逻辑(例如显示/隐藏相关组件).我测试默认情况下取消选中Checkbox,并且未调用事件处理程序,即使我已将其连接到Checked和Unchecked事件.我甚至在一个空白的WPF项目中重现了这一点,屏幕上有一个Checkbox,它的行为相同.
此默认行为的问题显然是某些其他组件尚未初始化.我认为WPF应该等到所有组件都被初始化,然后默认触发Checked事件.这可能不会被视为错误,但无论如何我都会在相关的MSDN页面上添加注释...
您应该能够检查 Window 上的 IsInitialized 或 IsLoaded 属性,以验证它已完成初始化/加载。否则,您需要检查 null 或在后面的代码中(在 InitializeComponent 之后)添加您的事件订阅。
此外,您可以调整访问元素的方式。例如,如果你有类似的东西:
<ListBox x:Name="listBox" SelectionChanged="OnListBoxSelectionChanged" />
Run Code Online (Sandbox Code Playgroud)
然后在你后面的代码中你可以通过几种方式获得列表框:
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 ...
}
Run Code Online (Sandbox Code Playgroud)
这是一个无线电按钮上的Checked事件.当我从xaml中删除Checked ="true"时,问题就消失了.(虽然在Window启动时会检查它).不确定这里发生了什么,但至少我没有必要改变任何重要的东西来修复它......