Last week we created the code to add and find a “person” in our SQLite database. This week we’ll finish up by creating the View and the ViewModel.
The View is where most of the action is, in this small demo project. We’ll have two views: one to capture the information and one to display it (see figure).
Create a page named EnterPerson.xaml to capture the user name. The user interface is very simple: there is a label to indicate that we are capturing a new person’s name, two entry boxes: one for the first and one for the last name, and three buttons: one for save, one for cancel and one for review that takes you to the second page.
Here is the XAML:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBases.EnterPerson">
<ContentPage.Content>
<StackLayout
Padding="20">
<Label
Text="New Person"
TextColor="Blue"
FontSize="18" />
<Entry
x:Name="FirstName"
Placeholder="First Name"
WidthRequest="150" />
<Entry
x:Name="LastName"
Placeholder="Last Name"
WidthRequest="150" />
<StackLayout
Orientation="Horizontal"
HorizontalOptions="Center">
<Button
BackgroundColor="Green"
TextColor="White"
WidthRequest="75"
Text="Save"
Clicked="OnSave" />
<Button
BackgroundColor="Red"
WidthRequest="75"
TextColor="White"
Text="Cancel"
Clicked="OnCancel" />
<Button
BackgroundColor="Blue"
WidthRequest="75"
TextColor="White"
Text="Review"
Clicked="OnReview" />
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Code Behind and View Model
The code-behind that goes with this has quite a bit of work that could be pushed into the ViewModel, but which I’ve kept where it is for the sake of simplicity (though I do use the ViewModel for saving the new person).
We begin, in the constructor by setting up…
public partial class EnterPerson : ContentPage {
private EnterPersonViewModel vm;
private int updateID = 0;
public EnterPerson() {
vm = new EnterPersonViewModel();
BindingContext = vm;
InitializeComponent();
}
…or, if we have an id, by obtaining the person for that ID:
public EnterPerson(int id) {
vm = new EnterPersonViewModel();
BindingContext = vm;
InitializeComponent();
Person Person = App.Database.GetPerson(id);
FirstName.Text = Person.FirstName;
LastName.Text = Person.LastName;
updateID = id;
}
The OnCancel method just clears out the controls,
public void OnCancel(object o, EventArgs e) {
Clear();
}
private void Clear() {
FirstName.Text = LastName.Text = String.Empty;
}
And the OnSave method delegates the work of saving the the ViewModel (shown below). The Review button moves us to the ListPeoplePage (not seen yet),
public void OnReview(object o, EventArgs e) {
Clear();
Navigation.PushAsync(new ListPeoplePage());
}
Here is the ViewModel,
public class EnterPersonViewModel {
public void AddPerson(string firstName,
string lastName,
int updateID) {
var newPerson = new Person {
FirstName = firstName,
LastName = lastName,
ID = updateID,
};
App.Database.SavePerson(newPerson);
}
}
You can see that it receives data from the page and adds that data (as a Person object) to the database.
The List People Page
The ListPeoplePage displays all the people in the database in a list, using a data template to dictate how they should appear (see image at top). Here is the XAML
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBases.ListPeoplePage">
<ContentPage.Content>
<StackLayout
Padding="30"
Spacing="1">
<Label
Text="People"
FontSize="18"
TextColor="Blue" />
<ListView
x:Name="PeopleList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout
Padding="5"
Spacing="1">
<Label
x:Name="FirstNameDisplay"
Text="{Binding FirstName}"
FontSize="12"
TextColor="Red" />
<StackLayout
Orientation="Horizontal">
<Label
Text="LastName:"
FontSize="10" />
<Label
Text="{Binding LastName}"
FontSize="10" />
</StackLayout>
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Notice that the FirstName and LastName use data binding. Also notice that the ItemsSource is not identified. This is done in an override of OnAppearing in the code behind,
protected override void OnAppearing() {
base.OnAppearing();
PeopleList.ItemsSource = App.Database.GetPeople();
}
We saw GetPeople last week, but to review quickly, that method looks like this:
public IEnumerable<Person> GetPeople() {
lock (locker) {
return (from c in database.Table<Person>()
select c).ToList();
}
}
The net effect is that we get all the people from the database, and display them in a list.