我的问题源于Stephen Cleary的an article。
基本上,有一个标签
<Label Content="{Binding UrlByteCount.Result}"/>
并且由viewmodel c.tor
设置UrlByteCount = new NotifyTaskCompletion<int>(
MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
到目前为止一切顺利。 现在我做了一个微不足道的改变:
UrlByteCount = new NotifyTaskCompletion<int>(MyStaticService.ImmediateSet(-1));
已定义
public static Task<int> ImmediateSet(int res)
{
var tcs = new TaskCompletionSource<int>();
tcs.SetResult(res);
return tcs.Task;
}
显然标签会立即显示-1。 好的,然后我添加一个带有viewmodel命令绑定的按钮,因为我想在单击按钮时设置标签。
跳过所有礼仪部分(委托命令等),核心功能又是:
private void TestLogic()
{
UrlByteCount = new NotifyTaskCompletion<int>( // FIX ME
MyStaticService.CountBytesInUrlAsync("http://www.example.com")); // FIX ME
}
我完全清楚没有工作,而且标签的内容仍然是-1,但我要问哪个是最好的解决这个问题的方法?
假设您已经找到第一部分的解决方案,并且单击按钮异步更改标签的内容(维护ui响应性),您能否确认以下代码是否是一致的方式防止&#34;双击&#34; (即&#34;多次执行&#34;)?
private async void TestLogic()
{
canRun = false;
((DelegateCommand)TestCommand).RaiseCanExecuteChanged();
await FoundASolution();
canRun = true;
((DelegateCommand)TestCommand).RaiseCanExecuteChanged();
}
private async Task<int> FoundASolution()
{
await Task.Delay(TimeSpan.FromSeconds(10));
return 21;
}
答案 0 :(得分:0)
假设您在UrlByteCount
setter中提升了属性更改事件,您的代码应该可以正常工作。绑定到UrlByteCount.Result
的事实并不意味着当您仅更改UrlByteCount
时,绑定不会刷新 - 它会。
至于你的第二部分 - 在启动长时间运行操作之前,可以通过Command.CanExecute
false来禁用按钮并通过Command.CanExecuteChanged
事件通知此事件。即使操作因异常而失败,也要确保再次启用它(因此请在try-finally块中包装)。您可能想要通知用户有关错误并允许他修复它(或者只是稍等一下,如果错误是网络故障),并重试操作,这在您的情况下是不可能的 - 按钮将保持禁用状态如果有错误。