我是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"
我对这一切都很陌生,并试着在我走的时候解决问题,但似乎无法找到这种特殊情况的答案。
答案 0 :(得分:1)
技术上的正确答案是NetworkViewModel
是一个类名,你需要一个类实例来调用你的方法。例如,您之前放入DataContext
的那个。
((NetworkViewModel)this.DataContext).SaveAll(Person);
但是最好阅读一篇关于Microsoft希望您使用WPF的command pattern。 MVVM比后面的代码好多了。
答案 1 :(得分:1)
如上所述,您应该遵循命令模式。您可以通过更新您的视图模型来执行此操作:
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
的视图模型上的属性。
希望这有帮助。