在视图中的按钮单击事件上使用视图模型中的方法
using a method from viewmodel on a buttonclick event in view
我是 mvvm 的新手,我正在尝试使用一种方法 "SaveAll" 将 observablecollection 保存到数据库中,我想从视图后面的代码中的 buttonclick 事件调用它,但它没有好像不可能。
这是我目前的代码。错误发生在 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"
我对这一切都是陌生的,我在尝试解决问题,但似乎找不到针对这种特殊情况的答案。
技术上的正确答案是 NetworkViewModel
是一个 class 名称,您需要一个 class 实例 来调用您的方法.例如你之前放入 DataContext
的那个。
((NetworkViewModel)this.DataContext).SaveAll(Person);
但是最好阅读有关 command pattern Microsoft 希望您与 WPF 一起使用的文章。它与 MVVM 一起工作比你后面的代码好得多。
如前所述,您应该遵循命令模式。您可以像这样更新您的视图模型:
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
的视图模型上的 属性。
希望这对您有所帮助。
我是 mvvm 的新手,我正在尝试使用一种方法 "SaveAll" 将 observablecollection 保存到数据库中,我想从视图后面的代码中的 buttonclick 事件调用它,但它没有好像不可能。
这是我目前的代码。错误发生在 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"
我对这一切都是陌生的,我在尝试解决问题,但似乎找不到针对这种特殊情况的答案。
技术上的正确答案是 NetworkViewModel
是一个 class 名称,您需要一个 class 实例 来调用您的方法.例如你之前放入 DataContext
的那个。
((NetworkViewModel)this.DataContext).SaveAll(Person);
但是最好阅读有关 command pattern Microsoft 希望您与 WPF 一起使用的文章。它与 MVVM 一起工作比你后面的代码好得多。
如前所述,您应该遵循命令模式。您可以像这样更新您的视图模型:
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
的视图模型上的 属性。
希望这对您有所帮助。