告诉WPF计算绑定
本文关键字:绑定 计算 WPF 告诉 | 更新日期: 2023-09-27 18:02:06
假设我有一个命令的执行方法,看起来像这样:
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调用)。
然而,一旦线程。睡眠结束,然后UI处理我的更改,并显示search绑定到的等待指示符。
现在,我知道传统的做法是对长时间运行的进程(Thread.Sleep)进行异步调用。
但是假设我不使用异步库,是否有一种方法可以指示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;
}
UPDATE: What I have try:
- 使用Dispatcher尝试单独向UI发送命令。
- 我也尝试了高优先级的Dispatcher。
你需要把你的工作推到后台线程中。绑定只有在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());
}
我同意其他人的观点,将长时间运行的进程转移到后台/异步操作是最好的方法。因为你的UI不会为用户冻结,也因为无论你做什么(刷新你的绑定,无论什么)都不会在UI中反映出来,而长时间运行的进程正在工作,因为UI线程将被阻塞。
也就是说,您的问题是您是否可以强制绑定从代码中求值/刷新,答案是肯定的。您可以通过在BindingExpression
上调用UpdateTarget
来完成此操作,如下所示:
labelTextBlock.GetBindingExpression(TextBlock.TextProperty).UpdateTarget();
在BindingExpression
上还有一种UpdateSource
方法,可以以大致相同的方式使用,只影响源而不是目标。
如果你的UI线程被阻塞了,它可能无法完成你所希望的,但这就是你强制绑定重新评估的方式。