かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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に対応してるからばっちりですね。