LemonteaのUnity部屋

C#とかのお話です~

Xamarin.Forms MessagingCenterを使う

こんにちは。レモンティーです。

今回は、MessagingCenterを使います。
これを使うと、ビューモデルやコンポーネント
お互いの情報をもたないでやりとりできます。

共有プロジェクト内だけでなく
各プラットフォームのコンポーネントとも
やりとりできて幅広く応用できます。

ざっくり言うと
Sendで発信されたメッセージをSubscribeが受信して
その時処理を実行する、というものです。
イベントハンドラみたいですね。

さっそく見ていきます。

送信

送信には↓を使います。

Send<TSender> (TSender sender, string message)

ジェネリック慣れてないと
なにやら難しそうですが見かけほどではないです。
Tsenderは送り主の型です。
例えば、これがMainPageに書かれていればMainPageでOKです。

また、第一引数は送り主のインスタンスなので
基本、thisと書けばOKですね。

messageはメッセージの識別用の文字列です。
TSenderとmessageが両方一致すると同じメッセージとみなされます。

受信

受信には↓を用います。

Subscribe<TSender> (object subscriber, string message, Action<TSender> callback, TSender source = null)

Tsenderとmessageは受信したいメッセージと同じものを設定します。

subscriberは受信するオブジェクトなのでsender同様thisでOKです。

Actionは受信時に実行する処理ですね。

使ってみる

それではシンプルなメッセージをやりとりしてみます。
以下ではMainPageとPage2という二つのページの
インスタンス間で試します。

Page2でAddNumberボタンが押されたらメッセージを送り、
受信したMainPageの変数numberを+1してLabelに表示します。

送信(Page2)

 private void AddNumbreButton_Clicked(object sender, EventArgs e)
        {
            MessagingCenter.Send<Page2>(this, "Test");
        }

受信(MainPage)

 public MainPage()
        {
            InitializeComponent();
            MessagingCenter.Subscribe<Page2>(this, "Test", (sender) =>
            {
                number += 1;
                NumberLabel.Text = number.ToString();
            });
        }

受信をやめる

もし、これ以上メッセージを受信しないようにしたい場合は

Unsubscribe<TSender> (object subscriber, string message)

を使います。これで
第一引数subscriberに設定したオブジェクトは
TSenderとmessageが一致したメッセージの受け取りをやめます。
なのでやめさせたいSubscriberと同じインスタンス内で
thisを渡して実行してあげればいいですね。

たとえば先ほどの例で
numberが10になったらそれ以上は
Page2からの"Test"メッセージを受け取らなくするには
受信側を

MessagingCenter.Subscribe<Page2>(this, "Test", (sender) =>
            {
                number += 1;
                NumberLabel.Text = number.ToString();

                if(number >= 10)
                {
                    MessagingCenter.Unsubscribe<Page2>(this, "Test");
                }
            });

と書き換えればOKです。

オブジェクトを添付する

MessagingCenterはメッセージと一緒にオブジェクトを渡すこともできます。
その場合も使い方にはあまり変化はなく、次のようになります。
(この例ではstringの文字列ですがC#のオブジェクトならなんでもOKだそうです)

送信

MessagingCenter.Send<Page2,string>(this, "SendText",TestEntry.Text);

受信

MessagingCenter.Subscribe<Page2,string>(this, "SendText", (sender,arg) =>
            {
                TextLabel.Text = arg;
            });

わたされた添付情報はargに格納されています。

受信停止

 MessagingCenter.Unsubscribe<Page2,string>(this, "Test");

メッセージの特定に不要なので添付情報の中身は要りません。

まとめ

長くなりましたが要は
・Sendで送ってSubscribeでキャッチ&処理
・受信中止はUnsbscribe
・オブジェクト添付も可
・共有と各プラットフォームを跨ぐことも可
です。

私もまだあまり使っていませんが
とても便利らしいですよ~ (^^)

今回はこれでおしまいです。

sawalemounity.hatenablog.com