使用ReactiveUI阻止双击

使用ReactiveUI阻止双击

问题描述:

我努力防止使用Xamarin Forms使用ReactiveUI双击按钮。假设我们有这样的命令:使用ReactiveUI阻止双击

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

它以正常的Xamarin Forms方式绑定到按钮。不幸的是,非常快的点击导致两个命令调用。

是否可以使用ReactiveUI修复它?

我更新的问题总结一下我试过:

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

不幸的是,它并没有帮助。当你在一个按钮上快速双击时,会执行两次命令执行。

我也尝试添加锁定语句或信号到'execute'方法,但它也失败了,因为执行并不是并行完成的。这也是为什么使用CanExecute方法不起作用的原因。

潜在的工作是一个丑陋的布尔标志。这个解决方案唯一的问题是我不得不在重新导航时重置它,这显然是可行的,但我不认为它是最好的解决方案。

+1

这听起来不对。 https://github.com/reactiveui/ReactiveUI/blob/f23538577ea7e567ab372c550adebebe9fdbb7f7/src/ReactiveUI/ReactiveCommand.cs#L566 在此问题中没有足够的信息可以回答。通常的方式是什么?你的实现是什么样的。请提供一个repro。 –

+0

@GeoffreyHuntley我更新了我的问题。我希望我的意思更清楚。我对ReactiveUI相当陌生,所以请原谅我的无知:)。我只想学习 – mierzynskim

您可以通过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是一条正确的道路,但即使你用bool标志来阻止它,下一个执行也不会并行完成,并且会成功执行 – mierzynskim

+0

你试图用CanExecute调试你的代码吗?你真的看到CanExecute为第二次点击返回true吗?执行死刑意味着什么不是平行进行的?如果您为CanExecute使用isBusy,则应在首次单击后立即禁用按钮。没有发生? –

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是一个observable,根据IsLogingExec值返回true或false。

ReactiveCommand.CreateFromTask具有第二个参数,如果该命令可以执行则返回true,否则返回false。如果命令无法执行,绑定命令的按钮将被禁用。

命令在执行时执行的第一件事是将IsLogingExec更改为false,这样就可以将LoginLog更改为false,并禁用commandbutton,然后执行导航方法。

IsLogingExec是一种反应性属性,这就是canLogin会对变化做出反应的方式。