LoginSignup
3
4

More than 5 years have passed since last update.

Xamarin.Formsでリアクティブプログラミングを試してみる

Last updated at Posted at 2017-05-10

Reactive Extensionsとかいうのを使ってリアクティブプログラミングとやらに挑んでみる。

リアクティブとかよく分かってないんで正しいアプローチなのか不安。

パッケージ追加

Reactive Extensions (Rx)1というパッケージを追加2する。

こいつが追加されているとObservableのイベントハンドラをラムダ式としてSubscribeの引数に指定できるようになる。

追加しなかった場合、監視側に IObserve を実装することになり、OnNext/OnError/OnCompleted の各メソッドの実装を強制される。うざい。

nuget.png

パッケージ追加に失敗

Could not install package 'System.Runtime.InteropServices.RuntimeInformation 4.0.0'.

とか言われて、パッケージ追加に失敗した場合は "System.Runtime.InteropServices.RuntimeInformation" を追加したあとに再実行するとうまくいく感じ。

コード

オブザーバーである MainPageViewModel が IObserver を実装していないことに注目。
OnNext/OnError/OnCompleted はメンバ関数ではなく、Subscribe の引数にラムダ式として指定している。

App.xaml.cs
using Xamarin.Forms;
using MyApp.Views;

namespace MyApp
{
    public partial class App : Application
    {
        public App() {
            InitializeComponent();
            MainPage = new MainPage();
        }
    }
}
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="MyApp.Views.MainPage">

    <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
        <Label Text="{Binding Greeting}" HorizontalTextAlignment="Center" />
        <Button Text="Greet" Command="{Binding GreetCommand}" />
        <Button Text="Clear" Command="{Binding ClearCommand}" />
    </StackLayout>

</ContentPage>
MainPage.xaml.cs
using Xamarin.Forms;
using MyApp.ViewModels;

namespace MyApp.Views
{
    public partial class MainPage : ContentPage
    {
        public MainPage() {
            InitializeComponent();
            BindingContext = new MainPageViewModel();
        }
    }
}
MainPageViewModel.cs
using System;
using System.ComponentModel;
using System.Windows.Input;
using System.Reactive.Linq;
using Xamarin.Forms;
using MyApp.Services;

namespace MyApp.ViewModels
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public string Greeting { get; set; }

        public ICommand GreetCommand { protected set; get; }
        public ICommand ClearCommand { protected set; get; }

        public MainPageViewModel() {
            Greeting = "...";

            GreetingService service = new GreetingService();

            service.Subscribe(
                value => {
                    System.Diagnostics.Debug.WriteLine("OnNext: " + value);
                    Greeting = value;
                    OnPropertyChanged(nameof(Greeting));
                },
                e => {
                    System.Diagnostics.Debug.WriteLine("OnError: " + e.Message);
                },
                () => {
                    System.Diagnostics.Debug.WriteLine("OnCompleted");
                }
            );

            GreetCommand = new Command(() => {
                service.Greet();
            });

            ClearCommand = new Command(() => {
                Greeting = "...";
                OnPropertyChanged(nameof(Greeting));
            });
        }

        protected void OnPropertyChanged(string propertyName) {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
GreetingService.cs
using System;
using System.Reactive.Subjects;

namespace MyApp.Services
{
    public class GreetingService : IObservable<string>
    {
        protected Subject<string> source = new Subject<string>();

        public IDisposable Subscribe(IObserver<string> observer) {
            return source.Subscribe(observer);
        }

        public void Greet() {
            source.OnNext("こんにちわ");
        }
    }
}

結果

Greet ボタン押下で GreetingService がオブザーバーに OnNext で渡した文字列が表示されました。

result.png

Rxの使い方ってこれで合ってるんだろうか・・・?

とりあえず以上です。

こちらを参考にしました

http://blog.okazuki.jp/entry/20111101/1320156608
http://blog.xin9le.net/entry/2012/01/15/163827


  1. 昔は System.Reactive ではなく、Rx.NET だったらしい。 

  2. PCLだけでなく、各プラットフォーム用プロジェクトにも追加しないとダメっぽい。やはりよくわからん。 

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4