假设我有一个命令的执行方法,如下所示:
private void Execute()
{
// Bound to a wait indicator in the UI
Searching = true;
// Do some long running process
Thread.Sleep(2000);
Searching = false;
}
当Searching设置为True时,绑定的UI元素将不会更新(即使Searching发送OnPropertyChanged调用)。
但是,一旦Thread.Sleep完成,然后UI处理我的更改并显示搜索绑定的等待指示符。
现在,我知道传统的智慧是使对长时间运行的进程(Thread.Sleep)的调用是异步的。
但是假设我没有使用Async库,有没有办法指示WPF立即执行搜索绑定?
这样的事情:
private void Execute()
{
// Bound to a wait indicator in the UI
Searching = true;
// MADE UP CODE
Binding.UpdateBindingNow("Searching");
// END MADE UP CODE
// Do some long running process
Thread.Sleep(2000);
Searching = false;
}
更新:我尝试了什么:
答案 0 :(得分:5)
您需要将工作推送到后台线程。在UI线程可以处理消息之前,绑定不会更新,直到操作完成才会发生。
Async是一种方法,但更经典的方法是使用BackgroundWorker
来执行此操作,这在所有版本的WPF中均受支持。
如果您使用的是.NET 4,也可以通过TPL执行此操作:
private void Execute()
{
// Bound to a wait indicator in the UI
Searching = true;
Task.Factory.StartNew( () => {
// Do long running work...
}).ContinueWith(t =>
{
// You can do work here, including touching UI controls/collections/etc
Searching = false;
}, TaskScheduler.FromCurrentSynchronizationContext());
}
答案 1 :(得分:1)
我同意其他人的说法,将长时间运行的流程转移到后台/异步操作是最好的方法。两者都是因为你的UI不会为用户冻结,也因为无论你做什么(刷新你的绑定,无论如何)都不会实际反映在UI中,而长时间运行的进程正在工作,因为UI线程将被阻止。 / p>
那就是说,你的问题是你可以强制绑定从代码中评估/刷新,答案是肯定的。您可以通过调用UpdateTarget
上的BindingExpression
来完成此操作:
labelTextBlock.GetBindingExpression(TextBlock.TextProperty).UpdateTarget();
UpdateSource
上还有一个BindingExpression
方法可以大致相同的方式使用,只影响来源而非目标。
同样,如果您的UI线程被阻止,它可能无法实现您所希望的,但这就是强制绑定重新评估的方式。