如何避免在初始化组件期间触发事件

本文关键字:事件 组件 何避免 初始化 | 更新日期: 2023-09-27 18:37:21

我有一个简单的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;
}