52 Weeks of Xamarin: Week 14 – Thrice (part 2)

In the previous posting I started a new project in Xamarin.Forms that I will reproduce ToDoReview2in
iOS and Android in coming posts.

Today, we’ll take a look at the second page in the Xamarin.Forms version: ListTasksPage.

This lists the tasks that you entered and persisted in the previous posting.

 

The Data

 

We start by creating a new Xamarin.Forms page: ListTasksPage.xaml.  Because we want to get our list from our database, we override OnAppearing in the code-behind,

 

 protected override void OnAppearing() {
     base.OnAppearing();
     ToDoList.ItemsSource = App.Database.GetToDos();
 }
 

This depends on our ToDoDatabase.cs file, which implements GetToDos(),

 public IEnumerable<ToDoItem> GetToDos() {
     lock (locker) {
         return (from c in database.Table<ToDoItem>()
                 select c).ToList();
     }
 }
 

This in turn relies on the SQLite_iOS method (for iOS),

 [assembly:Xamarin.Forms.Dependency(typeof(SQLite_iOS))]
 namespace ToDo.iOS {
     public class SQLite_iOS : ISQLite {
         
         public SQLite_iOS() {
         }
 
         public SQLite.SQLiteConnection GetConnection() {
         var path = "/users/jesseliberty/Data/ToDo.db";
 
             File.Open(path, FileMode.OpenOrCreate);
 
             var conn = new SQLite.SQLiteConnection(path);
 
             return conn;
         }
     }
 }

 

(Note that we are storing the data on my local hard disk rather than on the phone, to make debugging easier.)

Notice that this class implements ISQLite (to facilitate the dependency injection provided by the dependency service in Xamarin.Forms).  That interface is, as usual, extremely simple,

 public interface ISQLite {
     SQLiteConnection GetConnection();
 }

The XAML

With the ability to retrieve the ToDo items from the database, we’re now ready to create the XAML itself.  Here’s the top of the file,

 <ContentPage
   xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:local="clr-namespace:ToDo;Assembly=ToDo"
   x:Class="ToDo.ListTasksPage">
   <ContentPage.Resources>
     <ResourceDictionary>
       <local:DateTimeConverter
         x:Key="dtConverter" />
     </ResourceDictionary>
   </ContentPage.Resources>

Notice that the Resources section calls for a DateTimeConverter whose key is dtConverter.  This is defined in the helper class DateTimeConverter,

 public class DateTimeConverter : IValueConverter {
 
     public object Convert(object value, 
            Type targetType, 
            object parameter, 
            System.Globalization.CultureInfo culture) { 
         var time = (DateTime)value;
         return time.ToString("M/d/yyyy h:mm tt");
    }
 

As you can see, the convert method takes in a DateTime object and returns a properly formatted string.

Returning to the XAML,

<StackLayout
  Padding=30
  Spacing=1>
  <Label
    Text=Tasks
    FontSize=18
    TextColor=Blue />
  <ListView
    x:Name=ToDoList
    ItemTapped=OnSelected>
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <ViewCell.View>
            <StackLayout
              Padding=5
              Spacing=1>
              <Label
                x:Name=TaskNameDisplay
                Text={Binding TaskName}
                FontSize=12
                TextColor=Red />
              <StackLayout
                Orientation=Horizontal>
                <Label
                  Text=Priority:
                  FontSize=10 />
                <Label
                  Text={Binding Priority}
                  FontSize=10 />
                <Label
                  Text=Due:
                  FontSize=10 />
                <Label
                  Text={Binding DueDate, Converter ={StaticResource dtConverter}  }
                  FontSize=10 />
              </StackLayout>
            </StackLayout>
          </ViewCell.View>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</StackLayout>

Notice that we are binding to the TaskName, Priority and Date for each of the ToDo items we extracted from the database (above).  Most often, we would declare the ItemsSource property in the XAML but, as you’ll remember, we declared it in OnAppearing (repeated here),

 protected override void OnAppearing() {
     base.OnAppearing();
     ToDoList.ItemsSource = App.Database.GetToDos();
 }
 

Notice also that the list calls for an event handler when an item in the list is selected. For now, we just open an alert box to indicate that we have captured the correct item’s selection,

public void OnSelected(object o, ItemTappedEventArgs e) {
    var todoItem = e.Item as ToDoItem;
    DisplayAlert(Chosen!, todoItem.TaskName +  was selected, OK);
}

The result is the list of ToDo items as shown at the start of this posting.

 

Share

About Jesse Liberty

Jesse Liberty is an independent consultant and programmer with three decades of experience writing and delivering software projects. He is the author of 2 dozen books and multiple Pluralsight courses, and has been a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Xamarin Certified Mobile Developer and a Xamarin MVP, Microsoft MVP and Telerik MVP.
This entry was posted in Xamarin. Bookmark the permalink.

One Response to 52 Weeks of Xamarin: Week 14 – Thrice (part 2)

  1. Mike V says:

    Hi Jesse, very nice explained, but, what about relations in SQLite, should we a kinda dynamic query and relate our tables manually, do you know a better practice on this?

    thanks a lot!

Leave a Reply

Your email address will not be published.