C# PR

【Xamarin】Prismを使ってデータバインド(MVVM)する方法

アイキャッチ(c_sharp)
記事内に商品プロモーションを含む場合があります

こんにちは!
なかむぅです。

ついにアプリ開発に足を踏み入れることになりました。

使用するのはPrismを使用したXamarin.Formsです

Web開発でも取り入れているデータバインドも使用しているのですが

そもそもなんでデータバインドされるん

といった感じだったので、具体的にどういったものか調べてみました。

Prismを使ったXmarin.Formsで行われるデータバインドの仕組み

Xamarin.Formsのデータバインドは、Prismでプロジェクトを新規追加した時にはすでに実装されています。

生成されているMainPage.xamlを見てみると、ContentPageタグ内にTitleプロパティがあり、これが画面のタイトル部分です。

プロジェクト作成時には{Binding Title}と入っていますが、直書きすると代入文字列に変更されるはずなので試してみてください。

そしてTitleプロパティにセットされている{Binding Title}が、データバインドの一部の実装です。

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="MobileLab.Views.MainPage"
             Title="{Binding Title}">

    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
    </StackLayout>

</ContentPage>

この{Binding Title}は、MainPageViewModelのコンストラクタで代入されているTitleと紐づいていて、このTitleにセットする値が変更されると画面のタイトルも変更されます。

MainPageViewModel.cs

namespace MobileLab.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {
        public MainPageViewModel(INavigationService navigationService)
            : base(navigationService)
        {
            Title = "Main Page";
        }
    }
}
【Xamarin】prismを使ってデータバインド(MVVM)する方法

"Main Page""Hoge Page"に変更するとタイトルが変わるのが確認できるので試してみてください。

MainPageViewModel.cs

namespace MobileLab.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {
        public MainPageViewModel(INavigationService navigationService)
            : base(navigationService)
        {
            // Title = "Main Page";
            Title = "Hoge Page";
        }
    }
}
【Xamarin】prismを使ってデータバインド(MVVM)する方法

では、どのようにしてタイトルが変更されるのでしょうか。

{Binding Title}のTitleは、MainPageViewModelが継承しているViewModelBaseのプロパティです。

このTitleプロパティに値がセットされるとき、SetPropertyが呼ばれます。

ViewModelBase.cs

namespace MobileLab.ViewModels
{
    public class ViewModelBase : BindableBase, IInitialize, INavigationAware, IDestructible
    {
        protected INavigationService NavigationService { get; private set; }

        private string _title;
        public string Title ← コイツ
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }
        ・
        ・
        ・
    }
}

SetPropertyViewModelBaseが継承しているBindableBaseにあり、SetPropertyが呼ばれると

  1. RaisePropertyChanged
  2. OnPropertyChanged

といった順番で呼ばれて、最終的にPropertyChangedEventHandlerPropertyChangedが呼ばれてイベントが発生します。

このPropertyChangedイベントが発生することで、{Binding Title}で指定されている値が変更される仕組みですね。

BindableBase.cs

protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
    if (EqualityComparer<T>.Default.Equals(storage, value)) return false;

    storage = value;
    RaisePropertyChanged(propertyName);

    return true;
}
BindableBase.cs

protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
    OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
BindableBase.cs

protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
{
    PropertyChanged?.Invoke(this, args);
}
BindableBase.cs

public event PropertyChangedEventHandler PropertyChanged;

LabelとEntryをバインディングしてみる

タイトルだとイメージしづらいので、試しにHogeプロパティを作成してLabelタグとEntryタグをバインドさせみます。

MainPageViewModel.cs

namespace MobileLab.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {
        public MainPageViewModel(INavigationService navigationService)
            : base(navigationService)
        {
            Title = "Hoge Page";
        }

        private string _hoge;

        public string Hoge
        {
            get { return _hoge; }
            set { SetProperty(ref _hoge , value); }
        }
    }
}

MainPage.xamlにはLabelタグとEntryタグのそれぞれに同じプロパティを指定しましょう。

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="MobileLab.Views.MainPage"
             Title="{Binding Title}">

    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
        <Label Text="{Binding Hoge}"></Label>
        <Entry Text="{Binding Hoge}"></Entry>
    </StackLayout>

</ContentPage>

すると、Entryタグ内の文字が変更されると同時にLabelの値も変更されるようになっていると思います。

【Xamarin】prismを使ってデータバインド(MVVM)する方法

これはHogeプロパティのSetPropertyが呼ばれてPropertyChangedイベントが発火しているため、LabelタグとEntryタグの内容がバインディングされているようになっているんですね。


私の会社で一緒に働きませんか?

私が働く会社では、一緒に働いてくれるエンジニアを募集しています♪

こんな人がオススメ
  • 長く働いていても年収が全然上がらない…一気に年収を上げたい
  • 残業をしたくてしているわけではないので、残業代はしっかりと出して欲しい
  • やりたいことに挑戦させてもらえない…自分がしてみたいことに挑戦したい
  • 通勤時間が長すぎるから、できるだけ短くしたい
  • もっと勉強したいから、書籍代や資格の受験料など負担してくれるところに入りたい
  • 現場に駆り出されてからは放置プレイ…相談できる人も先輩も居ないので、自分の状況をちゃんと理解してくれるところで働きたい

上記内容に1つでも当てはまる場合は、ぜひお声がけください。
私のサイトから応募していただいた方にはお好きなギフト券5000円分プレゼントさせていただきます(条件あり)。

詳細ページ


まとめ

結構、ボタンを使用したバインディング方法を紹介している記事が多いですが、ボタンを押してからしかイベントが発生しないので

ボタンのクリックイベントと何が違うん

って感じで個人的にはいまいちよくわかりませんでした笑

この方法だとリアルタイムでLabelタグの文字が変更されているので、イメージしやすかったです。

以上、Prismを使ったXamarinのデータバインド方法についてでした!

いやここは違うだろ

と思った方はコメントいただけると嬉しいです。

最後までお読みいただきありがとうございました!

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です