Reputation: 611
I'm new to mvvm and I'm trying use a method "SaveAll"that saves the observablecollection to the database and I want to call it from a buttonclick event in code behind the view, but it doesn't seem to be possible.
This is the code I have so far. The error happens in 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();
}
}
}
and in the code behind view I got this
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
}
}
}
This doesn't seem to work I keep getting
"an object reference is required for the non static field, method or property"
I'm new to all this and trying to figure things out as I go but it seems I can't find the answer to this particular situation.
Upvotes: 0
Views: 5167
Reputation: 7414
As mentioned, you should follow the command pattern for this. You can do so by updating your view model like this:
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();
}
}
Since your SaveAll method did not actually use the Person
(you loop over all of them in your collection instead), I wouldnt pass the People parameter along.
Then, instead of having your code behind invoke the method. You can bind your button to the view model. Your XAML would look like this:
<Button x:Name="SavButton"
Command="{Binding }"
Content="Save All People" />
If you wanted to save a specific person that you have selected, you can pass them along in your binding too
<Button x:Name="SavButton"
Command="{Binding }"
CommandParameter="{Binding Path=SelectedPerson}"
Content="Save All People" />
public void Execute(object person)
{
People p = (People)person;
// save......
}
That is assuming you have data bound the selected person to a property on your view model called SelectedPerson
.
Hope this helps.
Upvotes: 1
Reputation: 77364
The technical correct answer would be that NetworkViewModel
is a class name, you need a class instance to call your method on. For example the one you put into your DataContext
earlier.
((NetworkViewModel)this.DataContext).SaveAll(Person);
But it would be better to read a about the command pattern that Microsoft wants you to use with WPF. It works a lot better with MVVM than your code behind.
Upvotes: 1