なんか20番煎じくらいな気がしますが、INotifyPropertyChangedを実装しようとするとフィールドやプロパティや変更通知やら、諸々実装が大変だ!というのがありますよね。これの簡単な解決策としては大きく二つはあると思っています。
- ReactivePropertyを利用する
- PropertyChanged.Fodyを利用する
前者はReactiveプログラミングをしないのであればオーバースペックな気がします。そこでFodyを利用する方法が検討対象になってきます。この辺りの詳細は次の記事に良くまとまっているように思います(全部目を通しきれていませんが)。
ただTeratailでVS4Macでうまくいかな〜いという声があったので、簡単な手順をまとめました。なお実際の実現方法は他にもパターンがありますが、細かいことは頑張って本家の英語を読みましょう。
動くコードはGithubに置いておきましたので確認してください。
それでは簡単に説明していきます。
パッケージを適用する
.NET Standardの共通コードが登録されているプロジェクトにNuGetからPropertyChanged.Fodyをインストールしましょう。
その他のプロジェクトに当てる必要はありません。
FodyWeavers.xmlを追加する
Fody系のライブラリを利用するときのお作法なのですが、プロジェクトのルートフォルダにFodyWeavers.xmlファイルを置いて、その中に適用するFody系ライブラリを指定します。今回は次のように記載しましょう。
<?xml version="1.0" encoding="utf-8" ?> <Weavers> <PropertyChanged/> </Weavers>
ViewModelを実装する
MainPageViewModel.csを作成し、次のように実装しましょう。
using System.ComponentModel; using System.Windows.Input; using Xamarin.Forms; namespace HelloFody { public class MainPageViewModel : INotifyPropertyChanged { public string Message { get; set; } = "Hello, Fody!"; public ICommand UpdateMessage => new Command(() => Message = "Updated Message!!"); public event PropertyChangedEventHandler PropertyChanged; } }
そしてこのViewModelをViewに適用します。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" xmlns:local="clr-namespace:HelloFody" x:Class="HelloFody.MainPage"> <ContentPage.BindingContext> <local:MainPageViewModel/> </ContentPage.BindingContext> <StackLayout Orientation="Vertical" HorizontalOptions="Center" VerticalOptions="Center"> <Label Text="{Binding Message}"/> <Button Text="Update message." Command="{Binding UpdateMessage}"/> </StackLayout> </ContentPage>
大きな改修は3点。
- BindingContextにMainPageViewModelを設定するように変更
- LabelのTextをリテラルからViewModelのMessageプロパティを表示するように変更
- Buttonを追加し、押下されたらMessageを更新するようCommandをバインド
動作確認
起動すると、まずは次のような画面が表示されます。
そしてボタンを押すとメッセージが更新されます。
ViewModelのプロパティは次のように実装しています。
public string Message { get; set; } = "Hello, Fody!";
通常では更新されても通知されないはずですが、動作から見てちゃんと変更通知が投げられていることが見て取れるでしょう。
以上です。