Xamarinの勉強 その1 GUIからDBへの追加・削除・更新を行う

こんにちは。そらです。
ブログを少しの間放置してしまっていました。9~10月の間はほとんどモチベーションが上がらず趣味の勉強のインプットがなかなかできませんでした。以前からやってみたいと思っていたモバイルアプリの開発をやっていきたいと思っています。
今回使用するライブラリXamarinについてはMicroSoftの公式のWebページを参照していただけると理解が進むかなと思っています。
この記事で使用する開発環境は、Windows10、Visual Studio2019です。開発環境構築については、先ほど紹介したXamarinの公式サイトのチュートリアルの通り構築してください。

今回の完成形は以下のような感じになります。

データベースにデータを導入することと、データの更新、削除ができるようになっています。また、起動時やデータの更新などの操作をしたときに、データベースの内容が表示されるようになっています。




動作動画

今回実装するプログラムの動作は以下の通りです。

頑張って作っていきます。

プロジェクト作成・設定

プロジェクトの作成から設定までをやっていきたいと思います。

右下の新しいプロジェクトの作成をクリックして、プログラムテンプレートからモバイル アプリ(Xamarin.Forms)を検索して、選択をして次へ進みます。ソリューション名を決定して、モバイルアプリのアプリテンプレートは空白を選んで進めていきます。

続いて、プロジェクトにSQLiteの追加をします。ソリューションを右クリックしてソリューションのNuGetパッケージの管理をクリックして参照からsplite-net-pclを検索してインストールします。インストールするときは、プロジェクト全体にインストールするようにしてください。

プログラムの実装編

データベースのテーブル作成

データベースのテーブルの作成は、クラスを作ることで行えます。今回は、ユニークキーがひとつ、要素が3つのものを作ることにしました。新規ファイルの追加からc#クラスの追加をしてください。ファイル名はクラス名を設定すればいいと思います。

using System;
using System.Collections.Generic;
using System.Text;
using SQLite;

namespace study
{
  public class Note
  {
    [PrimaryKey, AutoIncrement]
    public int ID { get; set; }
    public string Subject { get; set; }
    public string Content { get; set; }
    public DateTime Date { get; set; }
  }
}

namespaceは各自の作成したプロジェクト名によって異なります。テーブルの作成はできたので、データベースを操作するクラスを作っていきたいと思います。

データベースを操作するクラスの作成

データベースをアクセスしている最中はクリティカルセクションに位置付けられ、クリティカルセクション中に同時アクセスが起きた場合、データベースの情報の欠損などの問題が起きることが検討されるため、事前に防ぐ必要があります。そのために、データベースの操作は非同期で実装をしていきます。

using System.Collections.Generic;
using System.Threading.Tasks;
using SQLite;

namespace study
{
  public class NoteDatabase
  {
    readonly SQLiteAsyncConnection _database;

    public NoteDatabase(string dbPath)
    {
      _database = new SQLiteAsyncConnection(dbPath);
      _database.CreateTableAsync<Note>().Wait();
    }

    public Task<List<Note>> GetNotesAsync()
    {
      return _database.Table<Note>().ToListAsync();
    }

    public Task<Note> GetNoteAsync(int id)
    {
      return _database.Table<Note>()
             .Where(i => i.ID == id)
             .FirstOrDefaultAsync();
    }

    public Task<int> SaveNoteAsync(Note note)
    {
      if (note.ID != 0)
      {
        return _database.UpdateAsync(note);
      }
      else
      {
        return _database.InsertAsync(note);
      }
    }

    public Task<int> DeleteNoteAsync(Note note)
    {
      return _database.DeleteAsync(note);
    }
  }
}

クラスの実装は、ローカルの SQLite.NET データベースにデータを格納するのページを参考にしています。

モバイルの操作画面を編集する

デザインやlabelなどの配置をxamlを用いて編集していきたいと思います。MainPage.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="study.MainPage">

  <StackLayout>

  <Entry x:Name="SubjectEntry"
    Placeholder="Enter Subject" />
  <Entry x:Name="ContentEntry"
    Placeholder="Contents Entry" />

  <Button Text="Add to Database"
    Clicked="OnAddButtonClicked" />

  <ListView x:Name="listview"
     ItemTapped="TappedlistviewItem"
     HasUnevenRows = "True">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <StackLayout Orientation="Horizontal">
          <StackLayout>
            <Label Text="{Binding Subject}"/>
            <Label Text="{Binding Content}"/>
            <Label Text="{Binding Date}"/>
          </StackLayout>
        </StackLayout>
       </ViewCell>
      </DataTemplate>
     </ListView.ItemTemplate>
   </ListView >
  </StackLayout>

</ContentPage>

続いてc#のプログラムを用いてボタンを押したときの処理などを実装していきたいと思います。MainPage.csの内容の編集をしていきます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace study
{

  public partial class MainPage : ContentPage
  {

    public MainPage()
    {
      InitializeComponent();
    }

    protected override async void OnAppearing()
    {
      base.OnAppearing();
      listview.ItemsSource = await App.Database.GetNotesAsync();
    }

    private async void OnAddButtonClicked(object sender, EventArgs e)
    {
      if (!string.IsNullOrWhiteSpace(SubjectEntry.Text) && !string.IsNullOrWhiteSpace(ContentEntry.Text))
      {
        await App.Database.SaveNoteAsync(new Note
        {
          Subject = SubjectEntry.Text,
          Content = ContentEntry.Text,
          Date = DateTime.Now
        });

      SubjectEntry.Text = ContentEntry.Text = string.Empty;
      listview.ItemsSource = await App.Database.GetNotesAsync();
      }
    }

    private async void TappedlistviewItem(object sender, ItemTappedEventArgs e)
    {
      var item = e.Item as Note;
      string action = await DisplayActionSheet("Select Action?", "Cancel", null,"Update", "Delete");
      string check = await DisplayActionSheet("Really?", "No", null, "Yes");
      if(check == "Yes")
      {
        if (action == "Delete")
        {
          await App.Database.DeleteNoteAsync(item);
          listview.ItemsSource = await App.Database.GetNotesAsync();
        }
        else if (action == "Update")
        {
          if (!string.IsNullOrWhiteSpace(SubjectEntry.Text) && !string.IsNullOrWhiteSpace(ContentEntry.Text))
          {
            item.Subject = SubjectEntry.Text;
            item.Content = ContentEntry.Text;
            item.Date = DateTime.Now;
            await App.Database.SaveNoteAsync(item);
            SubjectEntry.Text = ContentEntry.Text = string.Empty;
            listview.ItemsSource = await App.Database.GetNotesAsync();
          }
          else
          {
            await DisplayAlert("Error", "Write the sentence in the text input.", "OK");
          }
        }
      }
    }
  }
}

ここまでで大体の実装が完了しました。次に、アプリケーションの起動時にデータベースを読み込み並びに作成などをするプログラムを書いておきます。

App.xaml.csの編集を行う

クラスの中に以下のプログラムを実装します。

static NoteDatabase database;

public static NoteDatabase Database
  {
    get
  {
    if (database == null)
    {
      database = new NoteDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "people.db3"));
    }
    return database;
  }
}

以上で実装はすべて完了です。

さいごに

この調子で勉強を進めていければいいなぁと思っています。開発環境構築が簡単にできることがとても助かりますね。
COCOA(新型コロナウイルス接触確認アプリ)がXamarinで作られているということを知り、やってみたかったけど手が出ない状態でしたがやっと着手できました。新しい勉強を始めるときはなかなか重い腰が上がらないですね。

参考文献

Xamarin の概要