告诉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。

告诉WPF计算绑定

你需要把你的工作推到后台线程中。绑定只有在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线程被阻塞了,它可能无法完成你所希望的,但这就是你强制绑定重新评估的方式。