在视图中的 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"
我对这一切很陌生,并试图在我去的时候弄清楚事情,但似乎我找不到这种特殊情况的答案。
如前所述,您应该遵循命令模式。您可以通过像这样更新视图模型来实现此目的:
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 比在后面的代码中工作得更好。