【问题标题】:c# - 'an unhandled exception of type 'System.NullReferenceException' [duplicate]c# - 'System.NullReferenceException' 类型的未处理异常
【发布时间】:2017-09-17 07:29:56
【问题描述】:

我是 MVVM 的新手,我有一个 Model.cs,其中包含一些“ID”和“PositionName”属性,我得到了 View.cs,其中包含 DataGrid,SelectedItems={Binding Items} 和 ItemSource={ Binding Position} 和一个带有 Command={Binding SHowEdits} 的按钮,点击后我在 'Items.PositionName == null' 处遇到了 NullReference 错误。
这是我的代码。

ViewModel.cs

class PositionVM : INotifyPropertyChanged
{
    private ObservableCollection<PositionModel> _position;
    private PositionModel _items;
    private ICommand _showedits;
    public ObservableCollection<PositionModel> Position
    {
        get
        {
            return _position;
        }
        set
        {
            _position = value;
            NotifyProperty("Position");
        }
    }
    public PositionModel Items
    {
        get
        {
            return _items;
        }
        set
        {
            _items = value;
            NotifyProperty("Items");
        }
    }
    public ICommand ShowEdits
    {
        get
        {
            if (_showedits == null)
                _showedits = new ShowEdit();
            return _showedits;
        }
        set
        {
            _showedits = value;
        }
    }
    public PositionVM()
    {
        Position = new ObservableCollection<PositionModel>();
        Position.Add(new PositionModel()
        {
            ID = 1,
            PositionName = "asd"
        });
    }
    public void ShowEditDialog()
    {
        if (Items.PositionName == null)
        {
            MessageBox.Show("ERROR");
        }
        else
        {
            PositionView view = new PositionView();
            Data.ID = view.txtid.Text;
            var z = new PositionView();
            z.ShowDialog();
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyProperty(String info)
    {
        if(PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

为什么会出现这个错误?我该如何避免呢?谢谢

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    我认为您对 ICommand 的问题。尝试将其作为财产:

    public ICommand ShowEditsCommand { get; set; };
    

    当然你需要创建它。我使用我的 Command 类,你也可以在第一次使用它,非常简单:

    /// <summary>
    /// Relay implementation of ICommand.
    /// </summary>
    public class RelayCommand : ICommand
    {
        private Action execute;
    
        private Predicate<object> canExecute;
    
        private event EventHandler CanExecuteChangedInternal;
    
        public RelayCommand(Action execute)
            : this(execute, DefaultCanExecute)
        {
        }
    
        public RelayCommand(Action execute, Predicate<object> canExecute)
        {
            if (execute == null)
            {
                throw new ArgumentNullException("execute");
            }
    
            if (canExecute == null)
            {
                throw new ArgumentNullException("canExecute");
            }
    
            this.execute = execute;
            this.canExecute = canExecute;
        }
    
        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
                this.CanExecuteChangedInternal += value;
            }
    
            remove
            {
                CommandManager.RequerySuggested -= value;
                this.CanExecuteChangedInternal -= value;
            }
        }
    
        public bool CanExecute(object parameter)
        {
            return this.canExecute != null && this.canExecute(parameter);
        }
    
        public void Execute(object parameter)
        {
            this.execute();
        }
    
        public void OnCanExecuteChanged()
        {
            EventHandler handler = this.CanExecuteChangedInternal;
            if (handler != null)
            {
                handler.Invoke(this, EventArgs.Empty);
            }
        }
    
        public void Destroy()
        {
            this.canExecute = _ => false;
            this.execute = () => { return; };
        }
    
        private static bool DefaultCanExecute(object parameter)
        {
            return true;
        }
    }
    

    在此之后,您需要在视图模型构造函数中对其进行初始化并将其绑定到方法:

    ShowEditsCommand = new RelayCommand(ShowEdits);
    

    其中 ShowEdits 是您在命令调用时需要运行的方法:

    public void ShowEdits()
    {
     // do something here
    }
    

    【讨论】:

      【解决方案2】:

      从这一行开始

      Items.PositionName == null
      

      抛出空引用异常,很明显Items为空。

      为什么Items 为空?

      Items 属性定义如下:

      public PositionModel Items
      {
          get
          {
              return _items;
          }
          set
          {
              _items = value;
              NotifyProperty("Items");
          }
      }
      

      当您尝试设置PositionModel 的值时,调用getter (get { return _items; }) 完成,以便获得对_items 指向的对象的引用。你得到的值为空。这意味着设置器尚未被调用,以便使用值初始化 _items,或者它已被初始化但稍后您的代码的另一部分已将其设置为 null。

      查看您的代码,我们看到了您的类的构造函数:

      public PositionVM()
      {
          Position = new ObservableCollection<PositionModel>();
          Position.Add(new PositionModel()
          {
              ID = 1,
              PositionName = "asd"
          });
      }
      

      显然,Items 没有在那里初始化。所以Items 有一个引用类型的默认值,null...

      【讨论】:

        猜你喜欢
        • 2013-09-04
        • 2015-12-17
        • 1970-01-01
        • 1970-01-01
        • 2018-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多