かずきのBlog@hatena

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

Xamarin.Formsでボタンの2度押しをReactivePropertyを使って抑止してみよう

お題の通りです。

こんな感じでReactiveCommandを普通に使うと連打すると2重で画面遷移したりします。

using Prism.Mvvm;
using Prism.Navigation;
using Reactive.Bindings;
using System;

namespace PrismUnityApp12.ViewModels
{
    public class MainPageViewModel : BindableBase, INavigationAware
    {
        private string _title;
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public ReactiveCommand NavigateCommand { get; }

        public MainPageViewModel(INavigationService navigationService)
        {
            this.NavigateCommand = new ReactiveCommand();
            this.NavigateCommand.Subscribe(async _ => await navigationService.NavigateAsync("NextPage"));
        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public void OnNavigatedTo(NavigationParameters parameters)
        {
            if (parameters.ContainsKey("title"))
                Title = (string)parameters["title"] + " and Prism";
        }
    }
}

解決策は簡単で2重起動防止機能が組み込まれてるAsyncReactiveCommandを使うだけでOKです。

using Prism.Mvvm;
using Prism.Navigation;
using Reactive.Bindings;
using System;

namespace PrismUnityApp12.ViewModels
{
    public class MainPageViewModel : BindableBase, INavigationAware
    {
        private string _title;
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public AsyncReactiveCommand NavigateCommand { get; }

        public MainPageViewModel(INavigationService navigationService)
        {
            this.NavigateCommand = new AsyncReactiveCommand();
            this.NavigateCommand.Subscribe(async _ => await navigationService.NavigateAsync("NextPage"));
        }

        public void OnNavigatedFrom(NavigationParameters parameters)
        {

        }

        public void OnNavigatedTo(NavigationParameters parameters)
        {
            if (parameters.ContainsKey("title"))
                Title = (string)parameters["title"] + " and Prism";
        }
    }
}

これでOK。このCommandを紐づけがボタンを連打しても2重で画面遷移したりしなくなりました。名前の通りasyncに対応してるからばっちりですね。