2017-10-06 14 views
2

ReactUIを使用してXamarinフォームを使用してボタンをダブルクリックしないように苦労しています。ReactiveUIを使用してダブルクリックを防止する

NextCommand = ReactiveCommand.CreateFromTask(async() => await HostScreen.Router.NavigateAndReset.Execute(new NewViewModel())); 

通常のXamarinフォームの方法でボタンにバインドされています。残念ながら、非常に高速なクリックは2つのコマンド呼び出しを引き起こします。

ReactiveUIを使用して修正することはできますか?

私が試したものを要約する質問を更新:残念ながら

var obs = Observable.FromAsync(async() => await HostScreen.Router.NavigateAndReset.Execute(new CitizensIndexViewModel())) 
        .Throttle(TimeSpan.FromSeconds(2)); 
LoginCommand = ReactiveCommand.CreateFromObservable(() => obs); 

、それは助けにはなりませんでした。非常に高速にボタンをダブルクリックすると、コマンドが2回実行されます。

私はlockステートメントやセマフォを 'execute'メソッドに追加しようとしましたが、実行が並行して行われないために動作しませんでした。これは、CanExecuteメソッドを使用する理由もありません。

潜在的には醜いブールフラグです。このソリューションの唯一の問題は、明らかに実行可能なバックナビゲーションでリセットする必要があることですが、これを最善の解決策とはみなしません。

+1

これは正しいとは言えません。実装をhttps://github.com/reactiveui/ReactiveUI/blob/f23538577ea7e567ab372c550adebebe9fdbb7f7/src/ReactiveUI/ReactiveCommand.cs#L566 で確認してください。この質問に答えるには十分な情報がありません。いつものやり方は何ですか?実装はどのように見えますか?レプロを提供してください。 –

+0

@GeoffreyHuntley質問を更新しました。私が意味することがより明確になることを願っています。私はReactiveUIにかなり新しいので、私の無知を私に許してください:)。私は学びたいだけ – mierzynskim

答えて

3

CanExecuteパラメータを渡すと、コマンドを実行できるかどうかを判断できます。 としてあなた缶がControlling Executabilityで参照してください。

var canExecute = this 
    .WhenAnyValue(
     x => x.UserName, 
     x => x.Password, 
     (u, p) => !string.IsNullOrEmpty(u) && !string.IsNullOrEmpty(p)); 
var command = ReactiveCommand.CreateFromObservable(this.LogOnAsync, canExecute); 

非常に同様の方法で、あなたのコマンドで待機インジケータを使用することができます。このことができます

bool busy = false; 
NextCommand = ReactiveCommand.CreateFromTask(
async() => 
{ 
    busy = true; 
    // do your studd here. 
    busy = false; 
}, 
!busy); 

希望を。

+0

私の更新された質問を参照してください。たぶんCanExecuteを使用するのは正しいパスですが、ブールフラグでブロックしても、次の実行は並行して実行されず、成功します。 – mierzynskim

+0

CanExecuteでコードをデバッグしようとしましたか? 2回目のクリックでCanExecuteがtrueを返すのが実際に分かりましたか?あなたは、処刑が並行して行われないということは何を意味しますか? CanExecuteにisBusyを使用している場合は、最初にクリックした後にボタンを無効にする必要があります。それは起こっていないのですか? –

1
var canLogin = this.WhenAnyValue(vm => vm.IsLogingExec, p =>!p); 
LoginCommand = ReactiveCommand.CreateFromTask(async() => { this.IsLogingExec = true; await HostScreen.Router.NavigateAndReset.Execute(new CitizensIndexViewModel()); } , canLogin); 

. 
. 
. 

private bool isLogingExec; 
public bool IsLogingExec{ 
    get => isLoggingExec; 
    set => this.RaiseAndSetIfChanged(ref isLogingExec, value); 
} 

canLoginは、IsLogingExec値に応じてtrueまたはfalseを返すobservableです。

ReactiveCommand.CreateFromTaskには2番目のパラメータがあります。コマンドを実行できる場合はtrue、そうでない場合はfalseです。コマンドを実行できない場合、コマンドをバインドしたボタンは無効になります。

実行時に最初に実行するのは、IsLogingExecをfalseに変更することです。つまり、canLoginがfalseに変更され、コマンドボタンが無効になり、navigateメソッドが実行されます。

IsLogingExecは反応的なプロパティです。つまり、canLoginは変更に反応します。

関連する問題