在视图中的 ButtonClick 事件上使用视图模型中的方法

本文关键字:视图 模型 方法 事件 ButtonClick | 更新日期: 2023-09-27 17:49:36

我是 mvvm 的新手,我正在尝试使用一种方法"SaveAll"将可观察集合保存到数据库中,我想从视图后面代码中的按钮单击事件调用它,但这似乎是不可能的。

这是我到目前为止的代码。错误发生在 NetworkViewModel.SaveAll(person( 中

namespace MyProject
{
    using Model;
    public class NetworkViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<Person> _networkList1 = new ObservableCollection<Person>();
        public ObservableCollection<Person> NetworkList1
        {
            get { return _networkList1; }
            set { _networkList1 = value; RaisePropertyChanged("NetworkList1"); }
        }
        public NetworkViewModel()
        { }
        public void SaveAll(Person person)
        {
            String dbConnectionString = @"Data Source =movieprepper.sqlite;";
            SQLiteConnection sqliteCon = new SQLiteConnection(dbConnectionString);
            sqliteCon.Open();
            var transaction = sqliteCon.BeginTransaction();
            String DeleteQuery = "delete from networking";
            SQLiteCommand DeleteCommand = new SQLiteCommand(DeleteQuery, sqliteCon);
            DeleteCommand.ExecuteNonQuery();
            foreach (Person p in _networkList1)
            {
                String Query = "insert into networking (firstname, lastname) values ('" + p.FirstName + "','" + p.LastName + "')";
                SQLiteCommand Command = new SQLiteCommand(Query, sqliteCon);
                Command.ExecuteNonQuery();
            }
            transaction.Commit();
            sqliteCon.Close();
        }
    }
}

在代码隐藏视图中,我得到了这个

namespace MyProject
{
   public partial class Networking : Window
   {
      public Networking()
      {
        InitializeComponent();
        this.DataContext = new NetworkViewModel();
       }
    private void btn_save_network_Click(object sender, RoutedEventArgs e)
    {
        NetworkViewModel.SaveAll(Person);// This is where error occurs
    }
   }
}

这似乎不起作用,我一直得到

"an object reference is required for the non static field, method or property"

我对这一切很陌生,并试图在我去的时候弄清楚事情,但似乎我找不到这种特殊情况的答案。

在视图中的 ButtonClick 事件上使用视图模型中的方法

如前所述,您应该遵循命令模式。您可以通过像这样更新视图模型来实现此目的:

    public class NetworkViewModel : INotifyPropertyChanged, ICommand
    {
        private ObservableCollection<Person> _networkList1 = new ObservableCollection<Person>();

        public event EventHandler CanExecuteChanged;
        public ObservableCollection<Person> NetworkList1
        {
            get { return _networkList1; }
            set { _networkList1 = value; RaisePropertyChanged("NetworkList1"); }
        }
        public NetworkViewModel()
        { }
        public bool CanExecute(object parameter)
        {
            return true;
        }
        public void Execute(object parameter)
        {
            String dbConnectionString = @"Data Source =movieprepper.sqlite;";
            SQLiteConnection sqliteCon = new SQLiteConnection(dbConnectionString);
            sqliteCon.Open();
            var transaction = sqliteCon.BeginTransaction();
            String DeleteQuery = "delete from networking";
            SQLiteCommand DeleteCommand = new SQLiteCommand(DeleteQuery, sqliteCon);
            DeleteCommand.ExecuteNonQuery();
            foreach (Person p in _networkList1)
            {
                String Query = "insert into networking (firstname, lastname) values ('" + p.FirstName + "','" + p.LastName + "')";
                SQLiteCommand Command = new SQLiteCommand(Query, sqliteCon);
                Command.ExecuteNonQuery();
            }
            transaction.Commit();
            sqliteCon.Close();
        }
    }

由于您的 SaveAll 方法实际上并未使用 Person(而是在集合中遍历所有这些方法(,因此我不会传递 People 参数。

然后,不要让代码隐藏,而是调用该方法。您可以将按钮绑定到视图模型。你的 XAML 将如下所示:

<Button x:Name="SavButton"
        Command="{Binding }"
        Content="Save All People" />

如果要保存所选的特定人员,也可以在绑定中传递他们

<Button x:Name="SavButton"
        Command="{Binding }"
        CommandParameter="{Binding Path=SelectedPerson}"
        Content="Save All People" />
public void Execute(object person)
{
     People p = (People)person;
     // save......
}

这是假设您已将数据将所选人员绑定到视图模型上名为 SelectedPerson 的属性。

希望这有帮助。

技术上的正确答案是,NetworkViewModel是一个类名,你需要一个类实例来调用你的方法。例如,您之前放入DataContext的那个。

((NetworkViewModel)this.DataContext).SaveAll(Person);

但是,最好阅读有关Microsoft希望您与 WPF 一起使用的命令模式的信息。它使用 MVVM 比在后面的代码中工作得更好。