読者です 読者をやめる 読者になる 読者になる

かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Xamarin.AndroidでReactivePropertyを使いやすくするライブラリを試作してみた

とりあえず。

以下のようなVMがあったとして

using Codeplex.Reactive;
using System;
using System.Reactive.Linq;

namespace App15
{
    public class MainPageViewModel
    {
        public ReactiveProperty<string> Input { get; private set; }
        public ReactiveProperty<string> Output { get; private set; }

        public ReactiveCommand ClearCommand { get; private set; }

        public MainPageViewModel()
        {
            this.Input = new ReactiveProperty<string>();

            this.Output = Observable.Merge(
                this.Input.Where(x => string.IsNullOrEmpty(x)).Select(_ => ""),
                this.Input.Where(x => !string.IsNullOrEmpty(x)).Select(x => x.ToUpper()))
                .ToReactiveProperty();

            this.ClearCommand = new ReactiveCommand();
            this.ClearCommand.Subscribe(_ => this.Input.Value = "");
        }
    }
}

こんな感じでActivityとつなぐことができます。

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Codeplex.Reactive.Extensions;
using ReactiveProperty.XamarinAndroid;
using ReactiveProperty.XamarinAndroid.Extensions;

namespace App15
{
    [Activity(Label = "App15", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        private readonly MainPageViewModel viewModel = new MainPageViewModel();

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // TwoWay binding
            this.SetBinding(
                // 対象のID
                Resource.Id.EditTextInput,
                // 対象のプロパティ
                (EditText x) => x.Text,
                // ソースのReactiveProperty
                this.viewModel.Input,
                // 更新タイミングのIO<Unit>
                (EditText x) => x.TextChangedAsObservable().ToUnit());

            // OneWay binding
            this.SetBinding(
                // 対象のID
                Resource.Id.TextViewOutput,
                // 対象のプロパティ
                (TextView x) => x.Text,
                // ソースのReactiveProperty
                this.viewModel.Output);

            // Command binding
            this.FindViewById<Button>(Resource.Id.ButtonClear)
                .ClickAsObservable()
                // IO<T>の発火でコマンドをキックする
                .SetCommand(this.viewModel.ClearCommand);
        }
    }
}

コレクション系は、前につくったライブラリのソースをごそっと持ってきたので、各種コレクションに対してToAdapterでIListAdapterがゲットできます。

Xamarin AndroidでIListやObservableCollectionをListViewに表示する - かずきのBlog@hatena

主な機能

  • コレクションをIListAdapterに変換するToAdapter拡張メソッド。
  • SetBindingメソッドによる単方向・双方向データバインド
  • SetCommandによるIObservableとReactiveCommandの接続
  • Viewを継承したクラスほぼ全てのイベントに対してEventNameAsObservableの拡張メソッド

です。さくっと作った割には少し気に入ってるので手を入れていってみようかな。

導入

NuGetに放流してあります。

NuGet Gallery | ReactiveProperty.XamarinAndroid 0.0.2