使用 MVVM 模式关闭打开的窗口,产生 System.NullReferenceException

我正在尝试使用 WPF C# 学习 MVVM 模式。在将信息保存到 sqlite 数据库后尝试关闭打开的窗口时,我遇到了错误。当发出保存新联系人的命令时,我在 HasAddedContact(this, new EventArgs()); 上收到错误消息


错误:System.NullReferenceException:“对象引用未设置为对象的实例。”


我的视图模型:


public class NewContactViewModel : BaseViewModel

    {

        private ContactViewModel _contact;


        public ContactViewModel Contact

        {

            get { return _contact; }

            set { SetValue(ref _contact, value); }

        }


        public SaveNewContactCommand SaveNewContactCommand { get; set; }


        public event EventHandler HasAddedContact;


        public NewContactViewModel()

        {

            SaveNewContactCommand = new SaveNewContactCommand(this);

            _contact = new ContactViewModel();

        }


        public void SaveNewContact()

        {

            var newContact = new Contact()

            {

                Name = Contact.Name,

                Email = Contact.Email,

                Phone = Contact.Phone

            };


            DatabaseConnection.Insert(newContact);

            HasAddedContact(this, new EventArgs());

        }

    }

保存新联系人命令:


    public class SaveNewContactCommand : ICommand

    {

        public NewContactViewModel VM { get; set; }


        public SaveNewContactCommand(NewContactViewModel vm)

        {

            VM = vm;

        }


        public event EventHandler CanExecuteChanged;


        public bool CanExecute(object parameter)

        {

            return true;

        }


        public void Execute(object parameter)

        {

            VM.SaveNewContact();

        }

    }

NewContactWindow.Xaml.Cs 背后的代码:


public partial class NewContactWindow : Window

    {

        NewContactViewModel _viewModel;


        public NewContactWindow()

        {

            InitializeComponent();


            _viewModel = new NewContactViewModel();

            DataContext = _viewModel;

            _viewModel.HasAddedContact += Vm_ContactAdded;

        }


        private void Vm_ContactAdded(object sender, EventArgs e)

        {

            this.Close();

        }

    }


动漫人物
浏览 215回答 1
1回答

人到中年有点甜

您正在构造函数中创建 NewContactWindow 的视图模型,正确地将其分配给 DataContext,并正确地向该事件添加处理程序。不幸的是,您还在资源中创建了相同视图模型的第二个实例,并且您手动设置所有绑定的 Source 属性以使用资源中没有事件处理程序的那个。Window.DataContext您在构造函数中设置的 是 Window XAML 中任何绑定的默认源。让它做它的事情。Mode=TwoWay我还删除了Bindings to 中的所有冗余内容TextBox.Text,因为该属性已定义为默认情况下所有绑定都是 TwoWay。我认为也没有UpdateSourceTrigger=PropertyChanged做任何必要或有帮助的事情:这会导致 Binding 在每次按下键时更新您的 viewmodel 属性,而不是仅在 TextBox 失去焦点时更新。但是我认为您没有对重要的属性做任何事情;没有验证或任何东西。但是 TextBox.Text是为数不多的实际使用它的地方之一,所以我把它留在了里面。您应该在其他窗口中删除类似的视图模型资源。它没有任何伤害,但充其量也没有用。在最坏的情况下,这是一个有吸引力的麻烦。用火把它烧死,把骨灰埋在半夜寂寞的十字路口下。<Window x:Class="Contacts_App.View.NewContactWindow"&nbsp; &nbsp; &nbsp; &nbsp; xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&nbsp; &nbsp; &nbsp; &nbsp; xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&nbsp; &nbsp; &nbsp; &nbsp; xmlns:d="http://schemas.microsoft.com/expression/blend/2008"&nbsp; &nbsp; &nbsp; &nbsp; xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"&nbsp; &nbsp; &nbsp; &nbsp; xmlns:local="clr-namespace:Contacts_App.View"&nbsp; &nbsp; &nbsp; &nbsp; xmlns:vm="clr-namespace:Contacts_App.ViewModel"&nbsp; &nbsp; &nbsp; &nbsp; mc:Ignorable="d"&nbsp; &nbsp; &nbsp; &nbsp; Title="New Contact Window" Height="250" Width="350">&nbsp; &nbsp; <Grid>&nbsp; &nbsp; &nbsp; &nbsp; <StackPanel&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Margin="10">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Label Content="Name" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <TextBox&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Text="{Binding Contact.Name, UpdateSourceTrigger=PropertyChanged}"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Margin="0,0,0,5"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Label Content="Email" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <TextBox&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Text="{Binding Contact.Email, UpdateSourceTrigger=PropertyChanged}"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Margin="0,0,0,5"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Label Content="Phone Number" />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <TextBox&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Text="{Binding Contact.Phone, UpdateSourceTrigger=PropertyChanged}"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Margin="0,0,0,5"/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Button&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Content="Save"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Command="{Binding SaveNewContactCommand}"/>&nbsp; &nbsp; &nbsp; &nbsp; </StackPanel>&nbsp; &nbsp; </Grid></Window>
打开App,查看更多内容
随时随地看视频慕课网APP