【问题标题】:Null Value Exception On Property That Is Not Null非空属性的空值异常
【发布时间】:2012-09-26 20:05:18
【问题描述】:

获取非空属性的 NullValueException

这里是 ViewModel 开头的代码,以及创建 ViewModel 对象并打开我正在使用 ViewModelt 的窗口的方法。在 SwitchName 属性上引发了异常。 _ciscoswitch.SwitchName 出现为空,因为 SwitchVewModel 中的 _ciscoswitch 为空。在 SwitchBrowser 构造函数中的 InitializeComponent() 处引发异常。查看调试器中的 SwitchVewModel 实例,_ciscoswitch 不为空。我尝试将 SwitchName 访问器更改为使用 CiscoSwitch.switchName 而不是 _ciscoswitch.SwitchName,但仍然失败。

class SwitchViewModel : INotifyPropertyChanged
{
      #region Construction
    /// Constructs the default instance of a SwitchViewModel
    public SwitchViewModel()
    {

    }


    public SwitchViewModel(CiscoSwitch cs)
    {
       _ciscoswitch = cs;
    }
      #endregion
    #region Members

    CiscoSwitch _ciscoswitch;
    #endregion

    #region Properties
    public CiscoSwitch CiscoSwitch
    {
        get
        {
            return _ciscoswitch;
        }
        set
        {
            _ciscoswitch = value;
        }
    }

    public string SwitchName
    {
        get { return _ciscoswitch.switchName; }
        set
        {
            if (_ciscoswitch.switchName != value)
            {
               _ciscoswitch.switchName = value;
                RaisePropertyChanged("switchName");
            }
        }
    }
    #endregion

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    #region Methods

    private void RaisePropertyChanged(string propertyName)
    {
        // take a copy to prevent thread issues
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion

}
}

SwitchBrowserWindow 的 XAML 我现在使用的唯一属性是 SwitchName 来尝试使其正常工作

<Window x:Class="CiscoDecodeWPF.SwitchBrowser"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:CiscoDecodeWPF="clr-namespace:CiscoDecodeWPF" IsEnabled="{Binding Enabled}"
    Title="SwitchBrowser" Height="500" Width="500" Background="GhostWhite">

<Window.Resources>
    <Style TargetType="{x:Type TreeViewItem}" x:Key="ModuleStyle">
        <Setter Property="Foreground" Value="Blue"/>
        <Setter Property="FontSize" Value="12"/>
    </Style>

    <Style TargetType="{x:Type TreeViewItem}" x:Key="RedModuleStyle" BasedOn="{StaticResource ModuleStyle}">
        <Setter Property="Foreground" Value="Red"/>
    </Style>
</Window.Resources>

<Window.DataContext>
    <CiscoDecodeWPF:SwitchViewModel/>
</Window.DataContext>
<Grid Margin="0,0,-211.4,-168">
    <StackPanel HorizontalAlignment="Stretch" Name="StackPanel1" VerticalAlignment="Stretch" Width="Auto" Margin="0,0,188.6,114">

        <StackPanel.Resources> 
            <Style TargetType="{x:Type Label}" x:Key="LabelStyle">
                <Setter Property="Foreground" Value="Blue"/>
                <Setter Property="FontSize" Value="12"/>
                <Setter Property="FontWeight" Value="Bold"/>
            </Style>
        </StackPanel.Resources>
        <Label Content="Switch Name:" Name="Label1" Height="25" HorizontalAlignment="Left"/>
        <Label Content="Software Version:" Name="Label2" HorizontalAlignment="Left" />
        <Label Content="Model Number:" Name="Label3" HorizontalAlignment="left"/>
        <Label Content="IP Address:" Name="Label4" HorizontalAlignment="left"></Label>
        <Label Content="Serial Number:" Name="Label5" HorizontalAlignment="Left"></Label>
        <Label Content="Show Tech Taken:" Name="Label6" HorizontalAlignment="left"/>
    </StackPanel>
    <StackPanel Margin="105,0,218,489">
        <StackPanel.Resources>
            <Style TargetType="{x:Type Label}" x:Key="LabelStyle">
                <Setter Property="FontSize" Value="12"/>
                <Setter Property="FontWeight" Value="Bold"/>
            </Style>
        </StackPanel.Resources>
        <Label Content="{Binding Path=SwitchName}" Name="SwitchNameLabel" HorizontalAlignment="left"/>
        <Label Content="Version" Name="VersionLabel" HorizontalAlignment="left"/>
        <Label Content="Model" Name="ModelNumberLabel" HorizontalAlignment="Left"/>
        <Label Content="IP" Name="IPAddressLabel" HorizontalAlignment="Left"/>
        <Label Content="Serial" Name="SerialLabel" HorizontalAlignment="Left"/>
            <Label Content="ST" Name="ShowTechLabel" HorizontalAlignment="Left"/>

    </StackPanel>

异常、堆栈跟踪和调用堆栈

System.NullReferenceException was unhandled by user code
  HResult=-2147467261
 Message=Object reference not set to an instance of an object.
  Source=CiscoDecodeWPF
StackTrace:
   at CiscoDecodeWPF.SwitchViewModel.get_SwitchName() in 

d:\Projects\CiscoDecodeWPF\CiscoDecodeWPF\SwitchViewModel.cs:line 50

内部异常:

CiscoDecodeWPF.exe!CiscoDecodeWPF.SwitchViewModel.SwitchName.get() 第 50 行 + 0xf 字节 C# [外部代码] CiscoDecodeWPF.exe!CiscoDecodeWPF.SwitchBrowser.SwitchBrowser(CiscoDecodeWPF.CiscoSwitch cs) 第 35 行 + 0x8 字节 C# CiscoDecodeWPF.exe!CiscoDecodeWPF.MainWindow.BrowseSwitchMenuItem_Click(object sender, System.Windows.RoutedEventArgs e) Line 1050 + 0x34 bytes C# [外部代码]

【问题讨论】:

  • 几乎可以肯定你的 XAML 有问题。请发布(并删除一些 C#)
  • 另外,发布整个堆栈跟踪。
  • 使用new SwitchBrowser(cs.FirstOrDefault()) 中的FirstOrDefault,您可以轻松地将null 传递为CiscoSwitch... 如果您的代码使用默认的public SwitchViewModel() 构造函数_ciscoswitch 也将是null...
  • @ChrisF,发布了 SwitchBrowserWindow 的 XAML,或者至少发布到使用 SwitchName 的位
  • @Kirk,发布了 Exeption 以及调试器为堆栈跟踪提供的内容

标签: c# xaml


【解决方案1】:

SwitchName中尝试以下代码:

 public string SwitchName
{
    get {
         if (_ciscoswitch != null)
         {   
           return _ciscoswitch.switchName;
         }
         else
         {
            return string.empty;
         }
      }
    set
    {
      if (_ciscoswitch != null)
      {
        if (_ciscoswitch.switchName != value)
        {
           _ciscoswitch.switchName = value;
            RaisePropertyChanged("switchName");
        }
      }
    }
}

如果您不想在SwitchName 中检查_ciscoswitch != null,则将DataContext = svm 放在InitizlizeComponent() 之前

代码:

public SwitchBrowser(CiscoSwitch cs)
{
    SwitchViewModel svm = new SwitchViewModel(cs);
    DataContext = svm;
    InitializeComponent();
 }

并从XAML 中删除以下代码。

<Window.DataContext>
<CiscoDecodeWPF:SwitchViewModel/>
</Window.DataContext>

希望它应该工作。

【讨论】:

  • 感谢 Jignesh,_ciscoswitch 不应该为空。我有一个 CiscoSwitch 对象的实例,我试图将其作为模型传入。
  • @DavidGreen 这一行试图从 viewmodel 中获取 Switchname,但当时 _ciscoswitch 为空。
  • 使用 ViewModel 的 CiscoSwitch 参数 New(),您在代码隐藏中创建它,并在 Initialization() 之后分配了 DataContext 值。但是在设计时,您刚刚使用默认的 New() 创建了 Viewmodel 的新对象。试试我的回答吧。
  • 那行得通。问题是有几个属性,显然我将不得不测试它们。如果有办法,我宁愿找到一种方法让 XAML 调用带有参数的构造函数。到目前为止我还没有找到。
  • @DavidGreen 在 InitializeComponent() 分配 DataContext 值之前查看我的更新答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-31
  • 2017-04-25
  • 1970-01-01
  • 1970-01-01
  • 2011-12-23
相关资源
最近更新 更多