'Update form with more than one parameter through binding in MVVM
I implemented a form with four input elements in a Xamarin.Forms app with MVVM. The four elements correspond to four properties of a model class.
Data is stored in a local SQLite database. I managed to deal with the creation, reading and deletion of data, but I am stuck with updating it. The problem I have is that I want to execute a command to perform the update with binding with more than one parameter. I tried several things, to no avail. So I came back to what worked last.
Model
public class LabWork
{
[PrimaryKey, AutoIncrement]
public int LabWorkId { get; set; }
public DateTime DateLabWork { get; set; }
public string TestName { get; set; }
public float TestValue { get; set; }
public string TestUnit { get; set; }
}
View
<ContentPage.Resources>
<ResourceDictionary>
<vm:LabWorkDetailVM x:Key="vm"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<DatePicker x:Name="dateLabWorkPicked"
Format="dd/MM/yyyy"
FontSize="Large"
Margin="30,0,0,0"
/>
<Entry x:Name="testName"
Margin="25,0,0,0"
/>
<Entry x:Name="testValue"
Margin="25,0,0,0"
FontSize="Large"
Keyboard="Numeric"
/>
<Entry x:Name="testUnit"
Margin="25,0,0,0"
FontSize="Large"
Placeholder="Ex. mg/l, μg/l..."
/>
<Button Text="Sauvegarder modifications"
x:Name="updateLabWorkButton"
Command="{Binding Source={StaticResource vm}, Path=UpdateCommand}"
CommandParameter={?????}/>
<Button Text="Effacer"
x:Name="deleteLabWorkButton"
Command="{Binding Source={StaticResource vm}, Path=DeleteCommand}" />
</StackLayout>
</ContentPage.Content>
ViewModel
public class LabWorkDetailVM
{
public Command DeleteCommand { get; set; }
public Command UpdateCommand { get; set; }
public LabWork SelectedLabWork { get; set; }
public LabWorkDetailVM()
{
DeleteCommand = new Command(Delete);
UpdateCommand = new Command(Update);
}
private void Update(object obj)
{
throw new NotImplementedException();
}
private void Delete()
{
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
conn.CreateTable<LabWork>();
int rows = conn.Delete(SelectedLabWork);
App.Current.MainPage.Navigation.PopAsync();
}
}
}
So far updating works from an event handler in View .xaml.cs file below, which I want to remove and replace with Update in the ViewModel
public partial class LabWorkDetailPage : ContentPage
{
public LabWork selectedLabWork;
public LabWorkDetailPage(LabWork selectedLabWork)
{
InitializeComponent();
(Resources["vm"] as LabWorkDetailVM).SelectedLabWork = selectedLabWork;
this.selectedLabWork = selectedLabWork;
dateLabWorkPicked.Date = selectedLabWork.DateLabWork;
testName.Text = selectedLabWork.TestName;
testValue.Text = selectedLabWork.TestValue.ToString();
testUnit.Text = selectedLabWork.TestUnit;
}
private void UpdateLabWorkButton_Clicked(object sender, EventArgs e)
{
selectedLabWork.DateLabWork = dateLabWorkPicked.Date;
selectedLabWork.TestName = testName.Text;
selectedLabWork.TestValue = float.Parse(testValue.Text, CultureInfo.InvariantCulture.NumberFormat);
selectedLabWork.TestUnit = testUnit.Text;
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
conn.CreateTable<LabWork>();
int rows = conn.Update(selectedLabWork);
Navigation.PopAsync();
//if (rows > 0)
// DisplayAlert("Success", "Experience successfully updated", "OK");
//else
// DisplayAlert("Failure", "Failed to update experience", "OK");
}
}
}
I'd appreciate some help on how to write the Update method in the ViewModel and corresponding implementation in the View xaml file.
Solution 1:[1]
i will implement binding as you asked in the comment.
<StackLayout BindableLayout.ItemsSource="{Binding LabWorkTest}"
>
<BindableLayout.ItemTemplate>
<DataTemplate>
<Entry x:Name="testName"
Margin="25,0,0,0"
Text={Binding TestName , Mode = TwoWays}/>
<Button Text="Sauvegarder modifications"
x:Name="updateLabWorkButton"
Command="{Binding Source={StaticResource vm}, Path=UpdateCommand}"
CommandParameter={Binding .}/>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
in the VM :
public class LabWorkDetailVM
{
public Command DeleteCommand { get; set; }
public Command UpdateCommand { get; set; }
public LabWork SelectedLabWork { get; set; }
private LabWork _labWorkTest;
public LabWork LabWorkTest{
get{ return _labWorkTest;}
set{ _labWorkTest= value; OnPropertyChanged("LabWork");}
}
public LabWorkDetailVM()
{
LabWorkTest = new LabWork{ ...};
DeleteCommand = new Command(Delete);
UpdateCommand = new Command<object>(Update);
}
private void Update(object obj)
{
LabWork _labWork =(LabWork) obj;
}
private void Delete()
{
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
conn.CreateTable<LabWork>();
int rows = conn.Delete(SelectedLabWork);
App.Current.MainPage.Navigation.PopAsync();
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
