C# 我是否可以扩展command类,使绑定到它的按钮自动禁用?
在我的应用程序中,我将按钮绑定到带有“MVVM”的命令。 我的命令实现如下:C# 我是否可以扩展command类,使绑定到它的按钮自动禁用?,c#,xaml,mvvm,xamarin.forms,C#,Xaml,Mvvm,Xamarin.forms,在我的应用程序中,我将按钮绑定到带有“MVVM”的命令。 我的命令实现如下: public Command CommandLoadStuff { get { return new Command(async () => { await DoLongStuff(); });
public Command CommandLoadStuff
{
get
{
return new Command(async () =>
{
await DoLongStuff();
});
}
}
问题是这些命令是异步的,用户可以多次单击它们,从而导致代码也执行多次
作为第一种方法,我使用CanExecute:
public Command CommandLoadStuff
{
get
{
return new Command(async () =>
{
AppIsBusy = true;
await DoLongStuff();
AppIsBusy = false;
},() => !AppIsBusy);
}
}
现在我想知道是否有比单独处理每个命令的CanExecute更好的方法了
由于我每次都用“new”初始化命令,我想知道类“command”是否不能相应地扩展。它应该在CanExecute的使用寿命期间阻止第二次单击按钮(可能在构造函数中?),并在命令执行完成后释放它。(可能在Dispose功能中?)
有没有办法实现这一点?您可以使用
IsEnabled
属性使按钮无法单击。
就像下面的代码一样
<Button
Text="click"
Command={Binding Button1Command}
IsEnabled={Binding AreButtonsEnabled} />
您可以使用IsEnabled
属性使按钮
无法单击。
就像下面的代码一样
<Button
Text="click"
Command={Binding Button1Command}
IsEnabled={Binding AreButtonsEnabled} />
据我所知,以这种方式扩展class命令是不可能的,因为Execute
是非虚拟的,您必须将Execute
操作传递给构造函数。无论如何,还是有办法的<代码>命令
源自具有以下接口的ICommand
公共接口ICommand
{
事件处理程序CanExecuteChanged;
无效执行(对象数据);
布尔CanExecute(对象数据);
}
您可以创建一个类AsyncBlockingCommand
(或其他任何类型),该类将返回CanExecute
中的相应值,具体取决于异步方法是否仍在运行(我知道async void
方法存在问题,请小心处理)
公共类AsyncBlockingCommand:ICommand
{
bool_canExecute=true;
履行职能;
公共异步阻塞命令(Func-toExecute)
{
_toExecute=toExecute;
}
公共事件处理程序CanExecuteChanged;
公共异步void执行(对象数据)
{
_canExecute=false;
RaiseCanExecuteChanged();
等待执行();
_canExecute=true;
RaiseCanExecuteChanged();
}
公共布尔CanExecute(对象数据)=>\u CanExecute;
private void RaiseCanExecuteChanged()的定义
{
CanExecuteChanged?.Invoke(此为EventArgs.Empty);
}
}
在执行异步方法之前,
\u canExecute
设置为false
,并引发CanExecuteChanged
。这样,您的按钮
将收到CanExecute
已更改并禁用自身的通知。反之亦然,在异步方法被调用之后。(可能必须在主线程上调用raisecancecutechanged
)以这种方式扩展class命令是不可能的,因为Execute
是非虚拟的,您必须将Execute
操作传递给构造函数。无论如何,还是有办法的<代码>命令源自具有以下接口的ICommand
公共接口ICommand
{
事件处理程序CanExecuteChanged;
无效执行(对象数据);
布尔CanExecute(对象数据);
}
您可以创建一个类AsyncBlockingCommand
(或其他任何类型),该类将返回CanExecute
中的相应值,具体取决于异步方法是否仍在运行(我知道async void
方法存在问题,请小心处理)
公共类AsyncBlockingCommand:ICommand
{
bool_canExecute=true;
履行职能;
公共异步阻塞命令(Func-toExecute)
{
_toExecute=toExecute;
}
公共事件处理程序CanExecuteChanged;
公共异步void执行(对象数据)
{
_canExecute=false;
RaiseCanExecuteChanged();
等待执行();
_canExecute=true;
RaiseCanExecuteChanged();
}
公共布尔CanExecute(对象数据)=>\u CanExecute;
private void RaiseCanExecuteChanged()的定义
{
CanExecuteChanged?.Invoke(此为EventArgs.Empty);
}
}
在执行异步方法之前,
\u canExecute
设置为false
,并引发CanExecuteChanged
。这样,您的按钮
将收到CanExecute
已更改并禁用自身的通知。反之亦然,在异步方法被调用之后。(可能必须在主线程上调用raisecancecutechanged
)一些想法:BebinInvokeOnMainThread
是从应该已经在主线程上的方法调用的。因此,我认为没有必要把它放在哪里。此外,您希望避免在主线程上执行长时间运行的计算。一些想法:BebinInvokeOnMainThread
是从应该已经在主线程上的方法调用的。因此,我认为没有必要把它放在哪里。此外,您希望避免在主线程上进行长时间运行的计算。非常感谢!这与我做的实验类似,但我忘记等待执行,因此我的命令立即再次启用!你的剪发会解决我的问题。谢谢!:)->我编辑了你的文章,因为调用函数需要两个参数。CanExecuteChanged?.Invoke(此为EventArgs.Empty);当然,事件需要参数。谢谢你的编辑,非常感谢!这与我做的实验类似,但我忘记等待执行,因此我的命令立即再次启用!你的剪发会解决我的问题。谢谢!:)->我编辑了你的文章,因为调用函数需要两个参数。CanExecuteChanged?.Invoke(此为EventArgs.Empty);当然,事件需要参数