【问题标题】:Trying to display a "please wait" message in WPF during a long-running operation尝试在长时间运行的操作期间在 WPF 中显示“请稍候”消息
【发布时间】:2013-01-14 11:31:36
【问题描述】:

我的 XAML 中有一个 please wait TextBlock,其 Visibility 属性绑定到我的 ViewModel 上的 IsBusy 属性(实现 INotifyPropertyChanged)。一个单独的按钮会启动一个长时间运行(2-3 秒)的进程,如下所示:

IsBusy = true;

try
{
    // Do some long-running process
}

finally
{
    IsBusy = false;
}

但是 please wait 消息永远不会出现。我假设操作在 UI 线程上运行,因此没有机会刷新?如果我在单独的线程上运行上述代码,它确实 工作,但我不希望用户在操作运行时做任何事情 - 我很高兴 UI freeze

如何显示 please wait 消息?或者我会更好地在后台线程上运行它并(以某种方式)在持续时间内锁定 UI?我正在使用 .Net 4 顺便说一句。

【问题讨论】:

  • 为什么不在后台线程中运行它,并将您的 Form/Window/UserControl/etc 的 IsEnabled 绑定到 IsBusy 属性?然后当它变得忙碌时,整个窗口被禁用以防止用户修改它而不锁定您的应用程序?
  • @Rachel 有时最简单的解决方案是最好的 - 谢谢!虽然现在遇到了另一个问题,但这是另一个 SO 问题的问题......
  • 好的,我已将该评论扩展为您的答案:)

标签: c# wpf visibility inotifypropertychanged textblock


【解决方案1】:

你是对的,它没有更新,因为你在同一个线程上运行代码,所以在你的进程完成之前渲染不会继续。

您说您没有使用后台线程,因为您不希望用户在操作运行时做任何事情,但是像这样完全锁定您的应用程序绝不是一个好主意。

更好的解决方案是将 Form/Window/UserControl/etc 的 IsEnabled 绑定到 IsBusy 属性。然后当它变得忙碌时,整个表单被禁用以防止用户修改它,同时不会锁定您的应用程序。

【讨论】:

    【解决方案2】:

    首先Visibility属性不是bool,所以如果你想将bool变量绑定到它你需要使用IValueConverter,第二,是的,你是对的,而UI线程正忙于你长时间运行的操作,它不会执行任何其他操作,包括可见性更改。

    我建议使用WPF Toolkit BusyIndicator 期望放置您自己的面板,它具有IsBusy bool 属性。

    另外冻结的UI也不友好,一般我用这个sn-p

    IsBusy = true;
    Task.Factory.StartNew(() => 
    { 
      // Do work. 
    })
    .ContinueWith(t=>IsBusy=false, 
                            TaskScheduler.FromCurrentSynchronizationContext());
    

    还要注意检查ContinueWith 方法中的错误,否则您将在Task dispose 上得到异常

    【讨论】:

      【解决方案3】:

      如果您在单独的线程上运行代码,您仍然可以通过 Dispatcher.BeginInvoke Method 访问 UI。

      if (!YOURCONTROL.Dispatcher.CheckAccess())
      {
          YOURCONTROL.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
              new Action(delegate()
              {
                  //do something with the control/form/...
              }));
      }
      else
      {
          //update your control
      }
      

      【讨论】:

      • 这就是我正在做的事情,但正如最初所说,我不想在后台线程中运行。事后看来,最好以可控的方式锁定 UI,而不是让它冻结。
      猜你喜欢
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      • 2021-10-29
      • 2010-12-31
      • 2011-06-15
      • 2011-11-30
      • 2014-05-12
      • 1970-01-01
      相关资源
      最近更新 更多