Realm Databaseを使ってCRUDを実装したシンプルなXamarin.Formsアプリを作ってみます。今回は前編としてCRUDのデータの作成(CREATE)と表示(READ)に該当する部分を作成します。データの表示にはComponentOne Studio for Xamarin(以下、C1 Xamarin)のFlexGridを使用します。
Realm Databaseとは?
Realm DatabaseはSQLiteと同じくローカルデータベースです。このデータベースは近年モバイルアプリをはじめてとして様々なアプリケーションで採用が進んでいます。Realm Databaseを使うメリットについてはオープンソース&クロスプラットフォームである、SQLiteより処理が高速である、使い始めるのが簡単など色々と挙げられます。詳細については公式サイトをご覧ください。
以下に作成手順を解説します。
Visual Studio 2017でXamarin.Forms (PCL)アプリを作成
まずはいつもどおりXamarin.Forms (PCL)アプリを作成します。現時点で最新のC1 Xamarin(2.3.20172.190)を使用するので各プロジェクトで使用するXamarin.Formsのバージョンを2.3.4.270に設定します。
Realm Databaseのインストール
Nuget パッケージ マネージャーから「Realm」を各プロジェクトにインストールします。 Realmはバージョン1.6をインストールします。
これに合わせてFodyは2.0.6、Newtonsoft.Jsonは9.0.1をインストールします。
また、Realmをインストールすると、各プロジェクトにFodyWeavers.xmlというファイルが作成されますが、UWPには作成されません。他のプロジェクトからコピーしておきます。
C1 Xamarin FlexGridのインストール
Nuget パッケージ マネージャーから「C1 Xamarin FlexGrid」を各プロジェクトにインストールします。
モデルの作成
データモデルを追加します。
public class DataModel : RealmObject { [PrimaryKey] public int Id { get; set; } public string LastName { get; set; } public string FirstName { get; set; } public float Height { get; set; } public float Weight { get; set; } }
ビューとビューモデルの作成(CREATE)
Realm Databaseにデータを入力するビューとビューモデルを作成します。 ビューのページにはデータを入力する Entry コントロールとRealm DatabaseへのCREATEを実行するボタンを配置します。
<?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="RealmDatabase.View.CreateData"> <ContentPage.Padding> <OnPlatform x:TypeArguments="Thickness" iOS="10, 20, 10, 0" Android="10, 20, 10, 0" WinPhone="10, 20, 10, 0" /> </ContentPage.Padding> <ContentPage.Content> <StackLayout> <Grid HorizontalOptions="FillAndExpand" VerticalOptions="Center"> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label Grid.Column="0" Grid.Row="0" Text="氏名(姓)"></Label> <Entry Grid.Column="1" Grid.Row="0" x:Name="lastname" Text="{Binding LastName}"></Entry> <Label Grid.Column="0" Grid.Row="1" Text="氏名(名)"></Label> <Entry Grid.Column="1" Grid.Row="1" x:Name="firstname" Text="{Binding FirstName}"></Entry> <Label Grid.Column="0" Grid.Row="2" Text="身長"></Label> <Entry Grid.Column="1" Grid.Row="2" x:Name="height" Text="{Binding Height}"></Entry> <Label Grid.Column="0" Grid.Row="3" Text="体重"></Label> <Entry Grid.Column="1" Grid.Row="3" x:Name="weight" Text="{Binding Weight}"></Entry> </Grid> <Button x:Name="writebtn" Text="入力したデータを登録" Command="{Binding WriteDataCommand}"></Button> </StackLayout> </ContentPage.Content> </ContentPage>
ビューのコードビハインドではバインディングコンテキストを設定します。
public partial class CreateData : ContentPage { public CreateData() { InitializeComponent(); var createdatavm = new CreateDataViewModel(); BindingContext = createdatavm; } }
ビューモデルではWriteDataメソッドをWriteDataCommandコマンドで呼び出します。WriteDataメソッドでRealm Databaseに入力データを追加しています。
public class CreateDataViewModel : INotifyPropertyChanged { Realm realm = Realm.GetInstance(); private string lastname; public string LastName { get { return lastname; } set { lastname = value; OnPropertyChanged("LastName"); } } private string firstname; public string FirstName { get { return firstname; } set { firstname = value; OnPropertyChanged("FirstName"); } } private string height; public string Height { get { return height; } set { height = value; OnPropertyChanged("Height"); } } private string weight; public string Weight { get { return weight; } set { weight = value; OnPropertyChanged("Weight"); } } public ICommand WriteDataCommand { get; private set; } public CreateDataViewModel() { WriteDataCommand = new Command(WriteData); } public void WriteData() { realm.Write(() => { realm.Add(new DataModel() { Id = realm.All<DataModel>().Count() + 1, LastName = LastName, FirstName = FirstName, Height = float.Parse(Height, System.Globalization.CultureInfo.InvariantCulture), Weight = float.Parse(Weight, System.Globalization.CultureInfo.InvariantCulture) }); }); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
ビューとビューモデルの作成(READ)
Realm Databaseに作成したデータをFlexGridで表示するビューとビューモデルを作成します。 ビューのページにはFlexGrid コントロールを配置します。
<?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="RealmDatabase.View.ListData" xmlns:c1="clr-namespace:C1.Xamarin.Forms.Grid;assembly=C1.Xamarin.Forms.Grid"> <ContentPage.Padding> <OnPlatform x:TypeArguments="Thickness" iOS="10, 20, 10, 0" Android="10, 20, 10, 0" WinPhone="10, 20, 10, 0" /> </ContentPage.Padding> <ContentPage.Content> <StackLayout> <Grid VerticalOptions="FillAndExpand"> <c1:FlexGrid x:Name="grid" AutoGenerateColumns="False"> <c1:FlexGrid.Columns> <c1:GridColumn Header="氏名(姓)" Binding="LastName" /> <c1:GridColumn Header="氏名(名)" Binding="FirstName"/> <c1:GridColumn Header="身長" Binding="Height" /> <c1:GridColumn Header="体重" Binding="Weight" /> </c1:FlexGrid.Columns> </c1:FlexGrid> </Grid> </StackLayout> </ContentPage.Content> </ContentPage>
ビューのコードビハインドではバインディングコンテキストを設定します。また、FlexGridのItemSourceにビューモデル内でRealm Databaseにあるデータのコレクションを設定したAllDataを設定します。
public partial class ListData : ContentPage { public ListData() { InitializeComponent(); var listdatavm = new ListDataViewModel(); BindingContext = listdatavm; grid.ItemsSource = listdatavm.AllData; grid.IsReadOnly = true; } }
ビューモデルではAllData にRealm Databaseにあるデータのコレクションを設定しています。
public class ListDataViewModel : INotifyPropertyChanged { Realm realm = Realm.GetInstance(); private ObservableCollection<DataModel> alldata; public ObservableCollection<DataModel> AllData { get { return alldata; } set { alldata = value; } } public ListDataViewModel() { AllData = new ObservableCollection<DataModel>(realm.All<DataModel>()); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
ビューとビューモデルの作成(トップページ)
最後に各ビューのページ(CreateDataとListData)に遷移するボタンを配置したトップページのビューとビューモデルを作成します。
<?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="RealmDatabase.View.MainPage"> <ContentPage.Padding> <OnPlatform x:TypeArguments="Thickness" iOS="10, 20, 10, 0" Android="10, 20, 10, 0" WinPhone="10, 20, 10, 0" /> </ContentPage.Padding> <ContentPage.Content> <StackLayout Padding="10"> <Button Text="Realm Databaseに登録" Command="{Binding NavToCreateCommand}"/> <Button Text="FlexGridで表示" Command="{Binding NavToListCommand}"/> </StackLayout> </ContentPage.Content> </ContentPage>
ビューのコードビハインドではバインディングコンテキストを設定します。
public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); var mainvm = new MainViewModel(); BindingContext = mainvm; } }
ビューモデルには各ページへのナビゲーションをNavToCreateCommand、NavToListCommand コマンドで追加しています。
class MainViewModel { public ICommand NavToListCommand { get; private set; } public ICommand NavToCreateCommand { get; private set; } public MainViewModel() { NavToListCommand = new Command(async () => await App.Current.MainPage.Navigation.PushAsync(new ListData())); NavToCreateCommand = new Command(async () => await App.Current.MainPage.Navigation.PushAsync(new CreateData())); } }
実行してみる
以上で作成完了です。アプリをビルドして実行してみます。
今回はCRUDのCREATE、READを実装しました。今後はUPDATE、DELETEも追加して後編として記事にしたいと思います。
作成したサンプルはこちらで公開しています。C1 Xamarinのライセンスも含まれていますので、NuGetパッケージを復元すれば実行可能です *1。
*1:NuGetパッケージを利用するには、GrapeCityのNuGetフィードソース( http://nuget.c1.grapecity.com/nuget/ )を、Visual Studioの環境に追加する必要があります。