放浪軍師のXamarin.Formsアプリ開発局

Xamarin.Forms+Prism+ReactivePropertyで素人がAndroidやUWPのアプリを右往左往しながら開発している様を発信していきます。性質上間違いも多いのでご注意ください。

ReactiveProperty<T>とReactiveCommandにお世話になりまくる話

放浪軍師のXamarin.Formsによるアプリ開発
今回はReactivePropertyとReactiveCommandについてのお話です。
まず、初めて訪問された方は以下をお読みください。

www.gunshi.info

ReactivePropertyってすげーな…

初期の頃、こんな記事を書きました。
www.gunshi.info

まぁ最近色々あってブログ更新していなかったので、初期の頃って言っても違和感バリバリではあるのですが、あれから業務の方でXamarinFormsでアプリ開発を進めていて、兎に角実感するのは
ReactivePropertyってSUGEEEEEEEE!!!!
って事ですね。滅茶苦茶便利です。ガンガン使ってます。
あの時twitterで教えてもらってなかったらと思うと少々ゾッとするレベルで頼りまくってます。感謝。

だから声を大にして言っておこうと思います。
初心者がXamarinやるならまず最初にReactivePropertyをインストールしろ!

…という事で、初心者向けにその為の手順を画像を交えて具体的に記載しておこうと思います。
俺自身、ちょっと離れただけで忘れちゃうから後で確認する為にもね。

インストール方法

新しいプロジェクトを立ち上げた後、真っ先にインストールを行ってください。手順は以下の通り。

[ツール]→[Nugetパッケージマネージャー]→[ソリューションのNuGetパッケージの管理]を開く。
f:id:roamschemer:20180703010833j:plain


[参照]→[ReactiveProperty]で検索→[ReactiveProperty]を選択→プロジェクトの横のチェックボックスにチェック(これで全部にチェックが入る)→[インストール]
f:id:roamschemer:20180703011224j:plain


ライセンスに同意する
f:id:roamschemer:20180703011543p:plain

以上です。簡単ですね。
そこそこやってる人なら、「Nugetから追加してください」でわかると思うんですが、俺はこの一文の意味が解らずに数時間使いましたからね。
俺のブログはそういった人に役に立てると嬉しいなと思っています。

ReactiveProperty< T >とReactiveCommandの使い方


MVVMで言うところのViewModelに該当する部分にコードを書くことになります。

using Reactive.Bindings;

名前空間を指定しておくと使えます。

public ReactiveProperty<string> HomuHomuLabel { get; set; } = new ReactiveProperty<string>();
public ReactiveCommand HomuHomuCommand { get; set; } = new ReactiveCommand();

という風に宣言して使用します。
この二つの違いですが、基本的にはReactiveProperty< T >を使い、その値の『変化』を拾います。
※< T >にはstring等の型が入ります。
ただし、Buttonのように押すという『行為』を拾いたい場合はReactiveCommandを使います。
この『変化』や『行為』を拾う方法は後述します。


ViewのXamlには以下のように書きます。

<Label Text = "{Binding HomuHomuLabel.Value}" />
<Button Text = "button"  Command="{Binding HomuHomuCommand}"/>

ReactiveProperty< T >の方は.Valueが必要ですが、ReactiveCommandには.Valueが不要である事に注意が必要です。
間違った場合、特にエラーも出ずに反応だけが無いので、「何故か動かない!」なんてときはまずこれを疑った方が良いですね。


ViewModelに話を戻します。ReactiveProperty< T >の内容を変更する場合

HomuHomu.Value = "赤井ほむら";

という風に書きます。こちらも.Valueが必要ですが、忘れてもVSが教えてくれるので安心です。


②で説明した値の『変化』やボタンを押した『行為』を拾うには

HomuHomuLabel.Subscribe(_ => HomuHomuLabelMethod());
HomuHomuCommand.Subscribe(_ => HomuHomuCommandMethod());

という風にSubscribeを使用する事で拾います。※購読と言う。
ここはReactiveProperty< T >もReactiveCommandも記述方法は同じです。


…以上です。基本的にはこのReactiveProperty< T >とReactiveCommandで押し切れるんじゃないかと思いますね。
勿論もっと沢山の機能があるみたいですけど、それはまた必要になったときや、ちゃんと理解してからでいいんじゃないですかね~。

ReactivePropertyの弱点

ReactivePropertyを使っていないコードを読む技術が養われません。
別にいいじゃんって思うかもしれませんが、巷にはReactivePropertyを使っていないサンプルコードがうじゃうじゃあります。
というか、ReactivePropertyを使っているサンプルコードの方がレアです。
全くの初心者の場合、サンプルコードが存在するか否かが大きく運命を左右するので、それが殆ど存在しないというのは結構なデメリットです。
俺もswitchをReactivePropertyで操作したサンプルが見つからなくて苦戦したりしました。
ReactiveCommandを使おうとしたんですよ…
実はこれ誤りで、スイッチを押す『行為』をReactiveCommandで拾うんじゃなくて、スイッチを押すことにより値が『変化』したのをReactiveProperty< T >で拾うのが正解でした。
ただ、ReactiveProperty< T >とReactiveCommandの性質さえきちんと押さえていれば、なんとかなるんじゃないかと思います。

詳しくは他の人に委ねる

当然ですが俺なんかよりもっともっと詳しい人たちが解説してくれているので確認した方が良いです。
かずきさんの記事
blog.okazuki.jp
@YSRKENさんの記事
qiita.com
どちらも大変お世話になっております。感謝感謝。

ついでに…誰かタスケテ…

※以下コードは動きません。

public ReactiveProperty<string>[] HomuHomuLabel { get; set; } = new ReactiveProperty<string>[2];
:
HomuHomuLabel[0].Subscribe(_ => HomuHomuCommandMethod1());
HomuHomuLabel[1].Subscribe(_ => HomuHomuCommandMethod2());
<Label Text = "{Binding HomuHomuLabel[0].Value}" />
<Label Text = "{Binding HomuHomuLabel[1].Value}" />

みたいに配列化って出来ないんですかねー。色々試してみたが動かないです…。
何か根本的な何かを間違っている気がするが…ワカラン。