我是否可以阻止WPF在我的代码中按顺序执行UI操作

时间:2017-03-13 16:00:52

标签: c# wpf

我遇到一个问题,即生成报告并将其发送到打印机需要几秒钟(创建RDLC报告容器很慢)。

为了确保用户知道发生了什么,我尝试在打印之前和之后更新状态行//.

Status = "Printing Report.";
OnPropertyChanged("Status");
//Create a hidden window to host the report control
ReportWindow rw = new ReportWindow();
rw.PrintReport();
rw.Close();  
Status = "Printing Report complete.";
OnPropertyChanged("Status");

我想要发生的是:

  1. 状态已更新,表示正在创建报告,并在完成报告后立即打印。
  2. 报告创建并打印几秒钟。
  3. 状态已更新以显示成功。
  4. 实际发生的是:

    1. UI上没有显示任何内容
    2. 几秒钟后,将创建并打印报告
    3. 状态已更新,表示正在创建报告,并在完成报告后立即打印。
    4. 之后立即更新状态以显示成功。这种情况发生的速度足够快,以至于第一条消息最多在屏幕上选通,以进行单个屏幕刷新;在最糟糕的情况下,除非我以断点打断,否则它根本就没见过。
    5. 我之前有过类似的问题,WPF优先考虑在UI线程上做一些缓慢的事情,然后再更新UI,以表明它将会忙碌几秒钟;但在这种情况下,我无法从UI线程中删除繁重的项目(或执行其他操作)以避免此问题。

1 个答案:

答案 0 :(得分:0)

  

...但在这种情况下,我无法从UI线程中移除重物(或做其他事情)以避免问题

在这种情况下,您可以创建一个新窗口,该窗口在单独的线程中启动并在报告打印时显示此窗口:

Wait screen during rendering UIElement in WPF

打印报告后,您只需关闭新窗口:

Window tempWindow = null;
Thread newWindowThread = new Thread(new ThreadStart(() =>
{
    SynchronizationContext.SetSynchronizationContext(
    new DispatcherSynchronizationContext(
        Dispatcher.CurrentDispatcher));

    tempWindow = new Window();
    tempWindow.Content = new ProgressBar() { IsIndeterminate = true };
    tempWindow.Closed += (ss, ee) =>
    Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);

    tempWindow.Show();
    System.Windows.Threading.Dispatcher.Run();
}));

newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();

ReportWindow rw = new ReportWindow();
rw.PrintReport();
rw.Close();

if (tempWindow != null)
    tempWindow.Dispatcher.Invoke(new Action(() => tempWindow.Close()));