2010-07-20 4 views
20

У меня есть приложение, на котором есть тонны элементов управления. И он имеет огромное количество мерцания, особенно при запуске.Мерцание в приложении Windows Forms

Я применил это fix к нему.

protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle |= 0x02000000; // WS_EX_COMPOSITED 
      return cp; 
     } 
    } 

Это сработало отлично - мерцание было уменьшено довольно невероятным количеством. Однако побочный эффект заключается в том, что кнопки «Свернуть», «Максимизировать» и «Закрыть» в правом верхнем углу окна не оживляют, когда я нажимаю на них или нажимаю на них (они все еще работают). Это придает приложению ощущения.

Как сохранить WS_EX_COMPOSITED, сохраняя при этом удобство использования кнопок Maximize, Minimize и Close?

Это происходит в Windows XP. Как отметил @fallenidol, это не проблема Windows 7.

+5

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

+0

BTW, я пробовал это исправление в тестовом приложении, работающем в Windows 7, и кнопки Maximize, Minimize и Close по-прежнему кажутся анимированными. – pmcilreavy

+0

@fallenidol. Это хорошо знать. Все мои клиенты находятся на XP. – AngryHacker

ответ

11

Я понял. Хитрость заключается в том, чтобы удалить флаг WS_EX_COMPOSITED после отображения формы. Полное объяснение и код в моем блоге:

How to get rid of flicker on Windows Forms applications

+0

Превосходно .. работал для меня – Marshal

+0

Хорошая документация. Спасибо за это. Upvoted. – C4u

+0

@ Хоссейн да, блог до сих пор не работает ... надеюсь, в какой-то момент в этом месяце восстановится. – AngryHacker

0

Вы должны попробовать стандартное свойство управления формами окон, называемое DoubleBuffered. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doublebuffered.aspx

+0

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

+0

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

+0

Я не могу сделать это для сторонних элементов управления, которые не раскрывают это свойство. – AngryHacker

4

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

 // Enable double duffering to stop flickering. 
     this.SetStyle(ControlStyles.DoubleBuffer, true); 
     this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
     this.SetStyle(ControlStyles.UserPaint, true); 
     this.SetStyle(ControlStyles.SupportsTransparentBackColor, false); 
     this.SetStyle(ControlStyles.Opaque, false); 
     this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
     this.SetStyle(ControlStyles.ResizeRedraw, true); 
+0

Весь смысл кода, который я написал, заключается в том, что вы делаете это один раз, а не для каждого отдельного пользовательского элемента управления (который содержит сотни + тонну сторонних элементов управления). – AngryHacker

+3

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

5

Я знаю, что этот вопрос немного старый, но лучше поздно, чем никогда. Я использовал ваш оригинальный пример, который вы связали, чтобы придумать тот, который переключает его при изменении размера, а затем переключает его назад, чтобы полностью рисовать все остальное. Надеюсь, это поможет другим найти решение этой проблемы. Как известно OP, свойства DoubleBuffering не решают мерцающие проблемы.

Вот работа вокруг, чтобы остановить мерцает, когда пользователь изменяет форму, но не портя чертеж элементов управления, таких как DataGridView, NumericUpDown и т.д. При условии, ваше имя форма «Form1»:

int intOriginalExStyle = -1; 
bool bEnableAntiFlicker = true; 

public Form1() 
{ 
    ToggleAntiFlicker(false); 
    InitializeComponent(); 
    this.ResizeBegin += new EventHandler(Form1_ResizeBegin); 
    this.ResizeEnd += new EventHandler(Form1_ResizeEnd); 
} 

protected override CreateParams CreateParams 
{ 
    get 
    { 
     if (intOriginalExStyle == -1) 
     { 
      intOriginalExStyle = base.CreateParams.ExStyle; 
     } 
     CreateParams cp = base.CreateParams; 

     if (bEnableAntiFlicker) 
     { 
      cp.ExStyle |= 0x02000000; //WS_EX_COMPOSITED 
     } 
     else 
     { 
      cp.ExStyle = intOriginalExStyle; 
     } 

     return cp; 
    } 
} 

private void Form1_ResizeBegin(object sender, EventArgs e) 
{ 
    ToggleAntiFlicker(true); 
} 

private void Form1_ResizeEnd(object sender, EventArgs e) 
{ 
    ToggleAntiFlicker(false); 
} 

private void ToggleAntiFlicker(bool Enable) 
{ 
    bEnableAntiFlicker = Enable; 
    //hacky, but works 
    this.MaximizeBox = true; 
} 
+0

Хорошая точка. У меня был этот код в моем приложении, но он забыл добавить его в мою запись в блоге. Обновит его через пару дней. – AngryHacker

0

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

+0

В качестве продолжения, похоже, у меня нет проблем с мерцанием, когда я переопределяю OnPaintBackground. Если я не хочу, чтобы фон был окрашен, я вызываю e.Graphics.Clear ([соответствующий цвет]) и возвращает, в противном случае вызывается метод базового события. Как я уже сказал, это «похоже» облегчает проблему. Однако мне интересно, какие непредвиденные последствия могут возникнуть. – Tebc

+0

Исправление. Вышеупомянутое переопределение, похоже, работает до тех пор, пока свойство минимального размера формы установлено на текущий размер. – Tebc

Смежные вопросы