我有一个简单的WPF页面,其中包含几个RadioButton,每个RadioButton都注册了一个Checked
事件处理程序,以便在更改选择时可能会发生某些事情。默认情况下,我希望选择其中一个单选按钮,因此我将 IsChecked
属性设置为 xaml 中的True
。像这样:
<RadioButton Checked="Radio_Checked" IsChecked="True">One</RadioButton>
<RadioButton Checked="Radio_Checked">Two</RadioButton>
这样做的问题是,在InitializeComponent
期间,IsChecked
属性会导致事件触发,这会导致 null 引用异常,因为我的事件处理程序尝试使用尚未初始化的元素。
目前,我已经通过检查页面是否在我的处理程序中IsInitialized
来解决此问题,如下所示:
private void Radio_Checked(object sender, RoutedEventArgs e)
{
if (this.IsInitialized)
{
if(MyRadioButton.IsChecked.GetValueOrDefault())
{
//SomeOtherElement is not initialized yet so it is null
SomeOtherElement.Visibility = Visibility.Visible;
}
}
}
我希望避免在所有事件处理程序中使用if (this.IsInitialized)
,因为这是我在 WinForms 中从未执行过的操作。
所以我的问题是,我可以以不同的方式处理这个问题,而不必向所有事件处理程序添加额外的代码吗?
老实说,我很惊讶你无论如何都没有检查处理程序中的null
......检查IsInitialised
只是检查null
的细微变化。处理null
值只是良好编程的一部分,让我们面对现实吧,它并没有真正添加大量代码。
因此,为了回答您的问题,我会说'不,如果您不希望发生NulReferenceException
,则无法检查事件处理程序中的null
(或IsInitialised
)"。
但是,在使用 MVVM 方法时,我们不会使用很多事件,而是尽可能使用数据绑定和ICommand
实例。当我们确实需要使用事件时,我们通常在 Attached Properties
中使用它们,但在那里您仍然需要检查null
值。
可以从 xaml 中删除事件处理程序,并在InitializeComponent();
后添加它
radioButton1.Checked+=Radio_Checked;
每个元素都按照它在 XAML 中的顺序创建。
<RadioButton x:Name="MyRadioButton" ...>
<YourElement x:Name="SomeOtherElement" ...>
我假设在您的 XAML 中,单选按钮放置在您引用的其他元素之前。在 InitializeComponent 中创建元素时,将设置所有属性并触发所有事件。所以SomeOtherElement在那一刻并不存在。解决方案非常简单:
<YourElement x:Name="SomeOtherElement" ...>
<RadioButton x:Name="MyRadioButton"...>
在单选按钮之前设置 SomeOtherElement。如果有理由不切换 XAML 中元素的顺序,请使用已提到的 null 检查:
if (SomeOtherElement != null)
{
SomeOtherElement.Visibility = Visibility.Visible;
}