【问题标题】:C# WPF Label Visibility ExceptionC# WPF 标签可见性异常
【发布时间】:2013-02-12 05:54:09
【问题描述】:

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

代码如下:

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

还有 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" />

这是我得到的错误: 文本内容为:“对象引用未设置为对象的实例”

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

非常感谢任何和所有帮助。

【问题讨论】:

  • NullReferenceException 的几乎所有情况都是相同的。请参阅“What is a NullReferenceException in .NET?”获取一些提示。
  • @JohnSaunders 谢谢。我真的应该开始独立调试,然后只问我是否需要帮助。尽管在这种情况下我可能仍然会问,因为我假设事件处理程序在所有 XAML 都已执行后运行。我会收藏那个链接,我觉得它可能会派上用场...
  • 请注意,下面@BrianS 的回答几乎说明了我的链接所说的内容:变量未初始化。他回答说它没有被初始化的原因是UI还没有初始化它。

标签: c# wpf xaml label visibility


【解决方案1】:

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

您的 XAML 是按顺序评估的,因此它会点击 ComboBox 并对其进行初始化(包括最初选择的值)并在标签初始化之前触发 SelectionChanged 事件。您会注意到,如果您更改 XAML 的顺序以使 Label 高于 ComboBox,您将不会遇到问题,因为 Label 将在事件之前初始化被解雇了。

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

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

由于您在ComboBox 中硬编码初始选择的值,您可以硬编码Label 的初始Visibility

但是您的代码中还有另一个问题 - ComboBoxSelectedValue 永远不会是字符串,因为您现在已经设置了它。 SelectedValue 将是 ComboBoxItem。为了查看您在ComboBoxItem 中输入的字符串值,您需要查看Content 属性。所以你需要这样的东西:

ComboBoxItem item = pointsSettings.SelectedValue as ComboBoxItem;
if(item.Content.ToString() == "between")
{
  ...
}

【讨论】:

  • 非常感谢,您的解决方案运行良好。一个快速的问题,在 XAML 中,我是否也应该将另一个标签(默认隐藏)也放在组合框上方,还是只需要在组合框之前定义默认可见标签?
  • 我添加这些信息主要是为了说明为什么会发生这种情况。因此,我的建议是从用户体验的角度将标签放置在应有的位置(上方或下方,以向用户提供正确体验为准),然后调整背后的代码以处理该场景。我很高兴这对你有用 - 另一个建议是你可能想研究 MVVM。有一个小的学习曲线,但它确实是构建 WPF 应用程序的标准方法,并且从长远来看会使生活变得更加轻松。
  • 我会在学习完 WPF 的基础知识后进行研究。再次感谢。
猜你喜欢
  • 2011-09-01
  • 2019-03-26
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 2014-10-19
  • 2010-10-17
  • 1970-01-01
  • 2012-01-30
相关资源
最近更新 更多