Могу ли я остановить 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. Статус обновляется, чтобы показать успех.

Что на самом деле происходит:

  1. Ничего не отображается в пользовательском интерфейсе
  2. Через несколько секунд отчет создается и печатается
  3. Статус обновляется, показывая, что отчет создается и будет напечатан, как только он будет готов.
  4. Сразу после этого статус обновляется, чтобы показать успех. Это происходит достаточно быстро, так что первое сообщение на экране отображается не более чем для одного обновления экрана; в худшем случае этого никогда не будет видно, если я не прервусь с точкой останова.

У меня раньше были подобные проблемы с тем, что WPF устанавливал приоритеты в выполнении чего-то медленного в потоке пользовательского интерфейса над обновлением пользовательского интерфейса, чтобы показать, что он будет занят в течение нескольких секунд; но в этом случае я не могу удалить тяжелый предмет из потока пользовательского интерфейса (или сделать что-то еще), чтобы избежать проблемы.

1 ответ

... но в этом случае я не могу удалить тяжелый элемент из потока пользовательского интерфейса (или сделать что-то еще), чтобы избежать проблемы

В этом случае вы можете создать новое окно, которое запускается в отдельном потоке, и отображать его во время печати отчета:

Экран ожидания при рендеринге UIElement в 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())); 
Другие вопросы по тегам