我遇到一种情况,试图阻止用户向按钮发送垃圾邮件,为此,我的命令将两个函数用作参数。第一个是确定按下哪个按钮然后执行适当导航操作的命令。现在,当您按下按钮时,会出现短暂的延迟,我认为是在加载数据的同时,然后按钮会在加载和显示新页面之前禁用毫秒。我希望他们在按下按钮后立即将其禁用,以使它们不会被发送垃圾邮件并加载多个相同类型的页面。
我要解决的此特定按钮按下操作使Page1 ViewModel从Web服务中检索SQL表。对此的调用在Page1ViewModel的构造函数中。
NavigateAsyncCommand = new RelayCommandAsync<object>(NavigateAsync, CanClickButton);
public async Task NavigateAsync(object parameter)
{
IsBusy = true;
Xamarin.Forms.Button b = parameter as Xamarin.Forms.Button;
string page = b.Text;
switch (page)
{
case "Page1":
await App.MainNavigation.PushAsync(new Views.Page1(), true);
IsBusy = false;
return;
//More cases here
}
}
第二个函数只是检查IsBusy的状态并返回反函数。
public bool CanClickButton(object parameter)
{
return !IsBusy;
}
在我的XAML中,我的按钮是这样实现的
<Button x:Name="StartButton"
Command="{Binding NavigateAsyncCommand}"
CommandParameter="{Binding Source={x:Reference StartButton}}"
Text="{Binding StartText}"
Grid.Row="1"/>
答案 0 :(得分:2)
我曾经遇到过这个问题。我的解决方法如下:
1)我创建了一个“反向布尔转换器”
public class ReverseBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
bool myValue = (bool)value;
return !myValue ;
}
catch { return true; } // or false
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Convert(value, targetType, parameter, culture);
}
}
2)我将转换器引用到xaml标头中
xmlns:converters="clr-namespace:MyNamespace.Converters"
3)我将转换器添加到资源字典中
<ResourceDictionary>
<converters:ReverseBooleanConverter x:Key="ReverseBool" />
</ResourceDictionary>
4)最后一步,我使用上述转换器将IsEnabled
绑定到视图模型的IsBusy
属性。
<Button x:Name="StartButton"
IsEnabled="{Binding IsBusy, Converter={StaticResource ReverseBool}}"
...
Grid.Row="1"/>
希望这会有所帮助!
答案 1 :(得分:0)
这是最接近您的初始代码解决方案的地方:
NavigateCommand = new RelayCommandAsync<object>(NavigateAsync, CanNavigate);
...
private async Task NavigateAsync(object parameter)
{
if (IsBusy)
return Task.CompletedTask;
IsBusy = true;
NavigateCommand.OnCanExecuteChanged();
var page = (string) parameter;
switch (page)
{
case "Page1":
await App.MainNavigation.PushAsync(new Views.Page1(), true);
//More cases here
}
IsBusy = false;
NavigateCommand.OnCanExecuteChanged();
}
private bool CanNavigate(object parameter) => !IsBusy;
...
<Button Command="{Binding NavigateCommand}"
CommandParameter="{Binding StartText}"
Text="{Binding StartText}"
Grid.Row="1"/>
每次CanExecute
值更改时,它将通知Button IsBusy
已更改。并且它将忽略通过的点击。
通常,您不应在ViewModel ctor
中进行任何长时间运行的操作,以使其尽可能简单。而是使用Page.OnAppearing
通知ViewModel它可以开始加载。