我在WPF4项目中使用MVVMLight,并且已经设置了一个ApplyCommand和一个UndoCommand,它们绑定到视图上的按钮。所有标准的东西,做了很多次。当用户单击按钮时,将调用WCF服务方法,并更新局部变量。 UndoCommandCanExecute方法使用此局部变量来确定是否可以运行UndoCommand。MVVMLight命令CanExecute在异步调用后不会触发
这工作正常,如果我同步WCF服务调用。但是,如果我使用异步调用,则CanExecute方法不会被触发,因此撤消按钮没有正确启用/禁用。
以下是两种命令调用的视图模型上的私有方法的简化版本。在实际的代码中,传入参数,这些参数用于服务调用。
private void CallServiceMethod() {
IsBusy = true;
Task t = new Task(() => {
Thread.Sleep(2000); // would really call a WCF service
SetUndoMessage();
IsBusy = false;
});
t.Start();
}
如前所述,为简单起见,WCF服务调用已被调用Thread.Sleep所取代。 SetUndoMessage()方法设置UndoCommandCanExecute方法使用的局部变量。 IsBusy是绑定到视图上的Telerik繁忙指示符的布尔,所以用户可以看到发生了某些事情。
运行此操作时,撤消按钮不能正确启用或禁用,直到您单击窗口上的某处。我在整个地方添加了Debug.WriteLine语句,并且可以看到在任务回调结束时未调用UndoCommandCanExecute方法。
我试图在任务回调的末尾添加以下两行,但它并没有帮助...
CommandManager.InvalidateRequerySuggested();
UndoCommand.RaiseCanExecuteChanged();
如果我删除了Thread.Sleep,然后正常工作,这听起来就像是延迟就是问题所在。此方法在任务结束之前结束,因此UndoCommandCanExecute方法不会触发。我不明白为什么它在我调用RaiseCanExecuteChanged方法或CommandManager时不会触发。
我尝试在我启动线程后立即添加t.Wait(),但直到服务调用结束后才显示忙指示,否定了整个目的。
任何任何想法如何解决这个问题?我想保持异步调用,因为这使我可以使用忙碌指示符,这是整个大型应用程序的标准,并且还向用户提供了一些反馈,指出发生了什么。
我被卡住了使用C#4的方式,所以C#5的新异步功能对我来说不可用,即使它们能解决问题。
任何人能帮助我们吗? –