gpt4 book ai didi

c# - 我可以扩展命令类,以便自动禁用绑定(bind)到它的按钮吗?

转载 作者:行者123 更新时间:2023-12-03 11:01:26 24 4
gpt4 key购买 nike

在我的应用程序中,我将按钮绑定(bind)到带有“MVVM”的命令。
我的命令实现如下:

        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 函数中?)

有没有办法做到这一点?

最佳答案

据我所知,以这种方式扩展类命令是不可能的,因为 Execute是非虚拟的,你必须通过 execute对构造函数的操作。不管怎样,还是有办法的。 Command源自 ICommand它具有以下界面

public interface ICommand
{
event EventHandler CanExecuteChanged;

void Execute(object data);

bool CanExecute(object data);
}

你可以创建一个类 AsyncBlockingCommand (或任何)将返回的将返回 CanExecute 中的相应值取决于异步方法是否仍在运行(我知道 async void 方法存在问题,因此请小心处理)

public class AsyncBlockingCommand : ICommand
{
bool _canExecute = true;
Func<Task> _toExecute;

public AsyncBlockingCommand(Func<Task> toExecute)
{
_toExecute = toExecute;
}

public event EventHandler CanExecuteChanged;

public async void Execute(object data)
{
_canExecute = false;
RaiseCanExecuteChanged();
await _toExecute();
_canExecute = true;
RaiseCanExecuteChanged();
}

public bool CanExecute(object data) => _canExecute;

private void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}

在执行异步方法之前, _canExecute设置为 falseCanExecuteChanged被提出。这样,您的 Button将收到 CanExecute 的通知已更改并禁用自身。调用异步方法后反之亦然。 (可能 RaiseCanExecuteChanged 必须在主线程上调用。)

关于c# - 我可以扩展命令类,以便自动禁用绑定(bind)到它的按钮吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61588535/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com