Удалите черное мерцание при первом показе Winform с установленным TransparencyKey

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

   Form f = new Form();
   f.BackColor = Color.Lime;
   f.TransparencyKey = f.BackColor;
   f.StartPosition = FormStartPosition.Manual;
   f.Bounds = Screen.PrimaryScreen.WorkingArea;
   f.Show();

Я получаю те же результаты, если создаю новый проект, устанавливаю фон формы на Lime и TransparencyKey на Lime, затем нажимаю Run.

Что я пробовал:

  1. Установите непрозрачность на 99% — такое же мерцание

  2. Принудительно WS_EX_COMPOSITED в OnCreateParams или с помощью SetWindowLong — такое же мерцание

  3. Показать окно меньше, или ширину 0, или за пределы экрана, а затем переместить в нужное место - вызывает проблемы с отображением, когда окна позади моей формы не перерисовываются правильно.

  4. Установка ControlStyles.Opaque, ControlStyles.UserPaint и нескольких других комбинаций ControlStyles и переопределение различных событий рисования/отрисовки фона — разные результаты, либо такое же мерцание, либо худшее мерцание, либо непрозрачная форма.

Переход на WPF может быть вариантом, но на самом деле не ищите «использовать WPF» в качестве ответа.


person eselk    schedule 04.05.2012    source источник
comment
Миллисекунда мерцания? Или это долгое, 1,5-секундное мерцание?   -  person Caffeinated    schedule 04.05.2012
comment
Миллисекунды, совсем недолго.   -  person eselk    schedule 04.05.2012
comment
Если я устанавливаю точки останова или задержки в определенных событиях в Visual Studio, я вижу, что форма сначала отображается как черная, а затем после обработки либо EraseBackground, либо Paint (в зависимости от того, какие ControlStyles я изменил) она рисуется как Известь, и сразу после этого она прозрачная. Переключение между лаймовым и прозрачным незаметным без дополнительных задержек/точек останова, но часть от черного к лаймовому... и я понятия не имею, почему WinForms сначала рисует его черным, поскольку у меня нет свойств, установленных на черный в все.   -  person eselk    schedule 04.05.2012


Ответы (1)


Установите Opacity на 0,01.

Если вам нужно, чтобы форма (или ее части) была видимой, переустановите непрозрачность после завершения создания формы:

Form f = new Form { Opacity = 0.01 };
f.Show();
f.BeginInvoke( new Action(() => f.Opacity = 0.99 ));

РЕДАКТИРОВАТЬ: обновлен очиститель, как предложил Тергивер.

person John Arlen    schedule 04.05.2012
comment
Работает как чемпион, спасибо! Работал над моим простым примером, а также над моей более сложной формой. В простом примере мне не нужен таймер, я просто сбрасываю непрозрачность в Form_Shown, но мне нужен таймер для моей более сложной формы... теперь у меня может даже быть моя форма, если это сработает :) - person eselk; 04.05.2012
comment
Вам вообще не нужно тратить таймер, просто используйте BeginInvoke. Что вам нужно, так это вернуть значение непрозрачности после завершения отправки текущего сообщения. BeginInvoke использует PostMessage, поэтому код будет выполняться после завершения текущей отправки. - person Tergiver; 05.05.2012