Небольшое мерцание при отображении модального диалога в .NET - PullRequest
5 голосов
/ 26 августа 2011

Я испытываю раздражающую проблему в моем приложении .NET Windows Forms .

У меня есть MainForm (A) и форма выполнения (B), которая отображается модально, когда яначать длинную операцию.

Когда операция заканчивается, и B закрывается, кажется, что окно, которое находится за моим приложением (обычно это происходит в Skype), выводится на передний план в течение нескольких миллисекунд, а затем мое приложениеактивируется нормально.

Это только небольшое мерцание, но раздражает.Здесь я напишу несколько советов, которые могут помочь найти решение:

  • Я вызвал showDialog без IWin32Window, но я добавил его безрезультатно.
  • Я закрыл B, используя Close(),затем я попытался Hide(), а затем Close(), но это не помогло.
  • Код, который выполняет ShowDialog (), вызывается из потока пользовательского интерфейса, поэтому он не выглядит проблемой с потоками.

Любая подсказка будет оценена.Заранее спасибо.

Ответы [ 6 ]

3 голосов
/ 12 марта 2012

Проверьте, не звоните ли вы Скрыть или Закрыть.Единственный способ избежать мерцания - это DialogResult.Upd: this.DialogResult = DialogResult.Ok

Проверка обработчиков OnFormClosing и т. Д. Они могут содержать неверный вызов метода.

Небольшая хитрость заключается в явной установке Owner

_dialog.Owner = this;
_dialog.ShowDialog();

Люди, которые редактируют пост - _dialog.ShowDialog(this), работают немного по-другому.Посмотрите на owner = ((Control) owner).TopLevelControlInternal; в декомпилированном коде

Отредактировано кем-то:

Или ...

_dialog.ShowDialog(this);

Эти вызовы идентичныв соответствии с MSDN

3 голосов
/ 20 января 2012

Я испытывал те же симптомы, и это сводило меня с ума.

Я наконец обнаружил, что проблема заключалась в том, что я звонил this.Dispose() вместо this.Close(), чтобы закрыть модальное окно. Я не уверен, почему я сначала позвонил this.Dispose().

После переключения методов проблема ушла.

Я понимаю, что эта ветка старая и это не является причиной вашей проблемы, я просто пытаюсь помочь любому, кто совершил ту же ошибку, что и я.

1 голос
/ 16 апреля 2018

В моем случае я столкнулся с той же проблемой в моем приложении winform VB.Net, но с немного другим сценарием. У меня был пользовательский элемент управления, который открывает диалог с помощью showdialog (), скажем dialog1, и при заполнении некоторых данных он скрывает dialog1 и снова открывает диалоговое окно 2 с помощью showdialog ().

В процессе скрытия диалогового окна 1 и показа диалогового окна 2 возникает мерцание, и оно на мгновение показывает окно на фоне.

После такого большого количества решений и обходных путей ни одно из них не работает для меня. Я нашел один обходной путь, который мог бы помочь другим.

Чтобы скрыть диалоговое окно1, я использовал Me.Hide (), решение состоит в том, чтобы изменить непрозрачность формы вместо вызова метода Hide ().

Me.Hide ()

Me.Opacity = 0

После этого обходного пути приложение работает нормально, без каких-либо мерцаний.

PS: Приведенные выше строки кода находятся в VB.Net, но этого достаточно для того, чтобы разработчик Winform-приложений .Net смог решить эту проблему.

0 голосов
/ 29 марта 2014
  1. Не вызывать Close для модального окна (оно не будет утилизировано и утечка памяти гарантирована)

  2. Установить this.DialogResult = DialogResult.OK

  3. Позвоните Dispose() от родителя, НИКОГДА из формы, которую вы закрываете

  4. Не забудьте утилизировать все свои компоненты, удерживаемые формой IContainer вDispose(bool) (VS реализации Designer для Dispose (bool) обычно недостаточно, чтобы не было утечек памяти)

0 голосов
/ 26 августа 2011

Хорошо, это звучит как

  1. В главном окне пользователь начинает длинную операцию
  2. Отображается модальное окно прогресса
  3. Операция завершает закрытиеокно прогресса
  4. Ваше главное окно не отображается сразу.Вместо этого что-то позади него просвечивает на секунду или меньше.
  5. Ваше главное окно завершает свою операцию перерисовки и становится видимым на 100%.
  6. Это происходит чаще, когда у вас запущены такие приложения, как Skype.

Если это так, есть много разных возможных причин.Например, в ваших видеодрайверах может быть ошибка, приводящая к задержкам компоновки за пределами экрана при определенных условиях.

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

Возможно, система просто ограничена в памяти, а ваша операция вызывает огромный обмендиск.Когда операция завершится, Windows может быть уведомлена о том, что ей нужно извлечь ранее замененную память с диска и вставить ее обратно в ОЗУ, что приведет к задержке.


Я бы запустил приложение с Ничего еще загружен, но диспетчер задач или монитор ресурсов и посмотреть, что происходит.Если проблема больше не возникает, подумайте о том, чтобы добавить больше оперативной памяти на ваш компьютер и / или игнорировать ее.

Если это все еще происходит, и использование вашей памяти почти ничего не оставляет, тогда, снова, добавьте ОЗУ или игнорируйте.

Если это все еще происходит, но использование памяти низкое, исследуйте ваш код, чтобы увидеть, чтовы делаете между закрытием диалогового окна и передачей управления основным окном обратно пользователю.

0 голосов
/ 26 августа 2011

Вы можете попробовать двойную буферизацию вашей формы с помощью в этом примере :

Тенденция к устранению мерцания при обновлении экрана.

...