C#WPF标签可见性异常

Luk*_*ord 1 c# wpf xaml label visibility

我正在尝试根据组合框的选定值显示标签.我正在使用VS2010.

这是代码:

private void pointsSettings_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (this.pointsSettings.SelectedValue.ToString() == "between")
        {
           pointsAboveLabel.Visibility = Visibility.Collapsed;
        }
        else
        {
           pointsAboveLabel.Visibility = Visibility.Visible;
        }
    }
Run Code Online (Sandbox Code Playgroud)

和XAML:

 <ComboBox Name="pointsSettings" SelectionChanged="pointsSettings_SelectionChanged">
     <ComboBoxItem Content="between" />
     <ComboBoxItem Content="above" IsSelected="True" />
     <ComboBoxItem Content="below" />
 </ComboBox>
 <Label Content="points" Name="pointsAboveLabel" />
 <Label Content="and" Name="pointsBetweenLabel" Visibility="Collapsed" />
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误: 在此输入图像描述 文本读取:"对象引用未设置为对象的实例".

我知道还有另一个非常相似的问题 - 事实上同样的错误 - 但是提供的解决方案(将变量初始化移动到InitializeComponent()方法调用之上)并不适合我,因为我没有对象初始化.

任何和所有的帮助都得到了最热烈的赞赏.

Bri*_*n S 5

发生这种情况是因为pointsSettings_SelectionChanged在UI完全初始化之前发生(您可以在callstack中看到它来自InitializeComponents()调用).因此标签尚未在UI中初始化,因此指向该标签的代码隐藏中的变量为null.所以它与其他问题实际上是同一个问题,但是WPF框架正在初始化变量,而不是你.

您的XAML按顺序进行评估,因此它会对其进行ComboBox初始化并对其进行初始化(包括最初选择的值),并在标签初始化之前触发SelectionChanged事件.如果你改变你的XAML的顺序,这样你会注意到Label上面ComboBox,你不会有问题,因为Label该事件被触发之前将被初始化.

要解决这个问题,我建议在pointsSetings_SelectionChanged方法中添加一个条件,以便在pointsAboveLabel为null时返回:

private void pointsSettings_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if(pointsAboveLabel == null) return;
    //rest of code
}
Run Code Online (Sandbox Code Playgroud)

既然你是在硬编码最初选择的值ComboBox,你可以硬编码初始VisibilityLabel.

但是,你有你的代码中的另一个问题- SelectedValueComboBox永远不会是一个字符串,你已经得到它安装了.该SelectedValue会是一个ComboBoxItem.为了查看您放入的字符串值ComboBoxItem,您需要查看该Content属性.所以你需要这样的东西:

ComboBoxItem item = pointsSettings.SelectedValue as ComboBoxItem;
if(item.Content.ToString() == "between")
{
  ...
}
Run Code Online (Sandbox Code Playgroud)