如何避免在InitializeComponent期间触发事件?

时间:2013-10-29 10:58:33

标签: c# wpf event-handling

我有一个带有几个RadioButton的简单WPF页面,每个RadioButton都注册了一个Checked事件处理程序,这样当选择被更改时,可能会发生一些事情。默认情况下,我希望选择其中一个RadioButton,因此我在xaml中将IsChecked属性设置为True。像这样:

<RadioButton Checked="Radio_Checked" IsChecked="True">One</RadioButton>
<RadioButton Checked="Radio_Checked">Two</RadioButton>

问题在于InitializeComponent期间IsChecked属性导致事件触发,这会导致空引用异常,因为我的事件处理程序尝试使用尚未初始化的元素。 / p>

目前我通过检查处理程序中的页面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中从未做过的事情。

所以我的问题是,我可以用不同的方式处理这个问题,而不必为我的所有活动人员添加额外的代码吗?

3 个答案:

答案 0 :(得分:3)

说实话,我很惊讶您还没有检查处理程序中的null ...检查IsInitialised只是检查null时的一小部分变化。处理null值只是良好编程的一部分,让我们面对它,它并没有真正添加大量代码。

因此,为了回答您的问题,我会说“不,如果您不想null,则无法在您的事件处理程序中检查IsInitialised(或NulReferenceException)发生'。

但是,在使用MVVM方法时,我们不使用很多事件,而是选择尽可能使用数据绑定和ICommand实例。当我们需要使用事件时,我们通常会在Attached Properties中使用它们,但您仍然需要检查null值。

答案 1 :(得分:1)

您可以从xaml中删除事件处理程序,并在InitializeComponent();

之后添加它
radioButton1.Checked+=Radio_Checked;

答案 2 :(得分:0)

每个元素都按照XAML中的顺序创建。

<RadioButton x:Name="MyRadioButton" ...>
<YourElement x:Name="SomeOtherElement" ...>

我假设在你的XAML中,RadioButton放在你引用的另一个元素之前。在InitializeComponent中创建元素时,将设置所有属性,并且还会触发所有事件。所以SomeOtherElement在那一刻不存在。 解决方案很简单:

<YourElement x:Name="SomeOtherElement" ...>
<RadioButton x:Name="MyRadioButton"...>

在RadioButtons之前设置SomeOtherElement。 如果有理由不在XAML中切换元素的顺序,那么使用已经提到的空检查:

if (SomeOtherElement != null)
{
    SomeOtherElement.Visibility = Visibility.Visible;
}