我有一个WPF / XAML窗口,其中包含一个给我带来问题的ComboBox。
窗口的ComboBox正在触发SelectionChanged
事件。
Debugger callstack显示我正在从Window构造器中间接调用SelectionChanged
。
问题是该窗口有一个事件Window_Loaded
,它会对数据成员进行一些最终初始化。由于此最终初始化尚未完成,因此SelectionChanged
事件因空引用异常而失败。
我有几种方法可以解决这个问题,但我想知道“最正确”的方法。
我可以在构造函数中完全初始化我的所有数据成员。这违反了保持构造函数最小化的概念。
我可以编码SelectionChanged事件处理程序来正确处理一些为null的数据成员。这是编码,只处理完全构建Window后永远不会发生的启动问题。
我可以使数据成员使用Lazy-Loaded,因此它们不会被Window_Loaded
初始化,而是首次访问它们时。似乎有点工作可以解决一个可以更简单地解决的问题。
我假设我不是第一个在Window Loaded事件之前处理UI事件的人。处理这个问题的首选方法是什么?
答案 0 :(得分:4)
我有一个类似的问题,在追踪它时,我有一个“a-ha”时刻。我有一个默认值为“IsSelected”,一个OnChange事件和一个自定义loadSettings方法。我首先指责了设置方法,但事实证明,选择默认值会在加载少量控件之前触发OnChange事件,包括触发空引用的父组合框。一旦我删除了“IsSelected”并允许默认值为null / empty,它工作正常,我的loadSettings方法负责设置默认值或上次使用的值。
答案 1 :(得分:3)
我通常会处理这样的(无休止的刺激性)SelectionChanged问题:
bool mySettingSelectionChangedInCode;
private void SetMySettingComboBox(string value)
{
mySettingSelectionChangedInCode = true;
mySettingComboBox.SelectedItem = value;
mySettingSelectionChangedInCode = false;
}
private void mySettingComboBox_SelectionChanged(object sender, EventArgs args)
{
if (mySettingSelectionChangedInCode)
return;
//...
}
答案 2 :(得分:2)
这对我有用:
if (System.Windows.Application.Current.MainWindow.IsInitialized == true)
{
//Do something
}
答案 3 :(得分:1)
最合适的方法是使用MVVM模式构建应用程序。在这种情况下,您不必处理这些问题。但我意识到,除非项目处于最初状态,否则不可能只迁移到MVVM。
无论如何,您描述的问题我将通过在您的窗口中定义IsInitialized
这样的标记来解决,并在true
事件处理程序中完成初始化后将其设置为Loaded
。然后,我会在SelectionChanged
处理程序中检查该标志,如果它是False
,则从方法返回而不做任何事情(忽略该调用)。
答案 4 :(得分:0)
这可能是因为您在设置ItemsSource属性后设置了组合框的SelectedValue。