Ответ 1
Глядя на проект, который вы опубликовали, мерцание действительно плохо, когда у вас выбрана первая вкладка с заполненными градиентом групповыми ящиками. При отображении второй или третьей вкладки вряд ли будет мерцания, если вообще.
Таким образом, проблема связана с элементами управления, которые вы показываете на этой вкладке. Быстрый взгляд на код настраиваемого класса группового поля, заполненного градиентом, дает более конкретную причину. Вы выполняете очень дорогостоящую обработку каждый раз, когда вы рисуете один из элементов управления групповыми элементами. Поскольку каждый элемент управления groupbox должен перерисовываться каждый раз при изменении размера формы, этот код запускается невероятно много раз.
Кроме того, у вас есть фон управления, установленный на "Прозрачный", который нужно подделать в WinForms, попросив родительское окно сначала вставить внутри окна управления, чтобы создать фоновые пиксели. Затем элемент управления берет верх над этим. Это также большая работа, чем заполнение контрольного фона сплошным цветом, например SystemColors.Control
, и это приводит к тому, что вы рисуете пиксели формы, когда вы изменяете размер формы, прежде чем групповые ящики смогут рисовать себя.
Вот конкретный код, о котором я говорю, из вашего настраиваемого класса управления групповыми группами, заполненного градиентом:
protected override void OnPaint(PaintEventArgs e)
{
if (Visible)
{
Graphics gr = e.Graphics;
Rectangle clipRectangle = new Rectangle(new Point(0, 0), this.Size);
Size tSize = TextRenderer.MeasureText(Text, this.Font);
Rectangle r1 = new Rectangle(0, (tSize.Height / 2), Width - 2, Height - tSize.Height / 2 - 2);
Rectangle r2 = new Rectangle(0, 0, Width, Height);
Rectangle textRect = new Rectangle(6, 0, tSize.Width, tSize.Height);
GraphicsPath gp = new GraphicsPath();
gp.AddRectangle(r2);
gp.AddRectangle(r1);
gp.FillMode = FillMode.Alternate;
gr.FillRectangle(new SolidBrush(Parent.BackColor), clipRectangle);
LinearGradientBrush gradBrush;
gradBrush = new LinearGradientBrush(clipRectangle, SystemColors.GradientInactiveCaption, SystemColors.InactiveCaptionText, LinearGradientMode.BackwardDiagonal);
gr.FillPath(gradBrush, RoundedRectangle.Create(r1, 7));
Pen borderPen = new Pen(BorderColor);
gr.DrawPath(borderPen, RoundedRectangle.Create(r1, 7));
gr.FillRectangle(gradBrush, textRect);
gr.DrawRectangle(borderPen, textRect);
gr.DrawString(Text, base.Font, new SolidBrush(ForeColor), 6, 0);
}
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
if (this.BackColor == Color.Transparent)
base.OnPaintBackground(pevent);
}
И теперь, когда вы видели код, красные предупреждающие флаги должны подниматься. Вы создаете кучу объектов GDI + (кисти, ручки, регионы и т.д.), но не можете Dispose
любой из них! Почти весь этот код должен быть заключен в выражения using
, Это просто небрежное кодирование.
Выполнение всей этой работы стоит того. Когда компьютер вынужден уделять столько времени средствам управления, другие вещи отстают. Вы видите мерцание, поскольку оно напрягается, чтобы не отставать от размера. Это ничем не отличается от всего, что перегружает компьютер (например, вычисляет значение pi), это очень просто сделать, когда вы используете так много настраиваемых элементов управления, как вы здесь. Прозрачность в Win32 затруднена, и так много пользовательской 3D-графики. Это делает пользовательский интерфейс неудобным для пользователя. Еще одна причина, по которой я не понимаю, что устремляться от собственного контроля.
У вас действительно есть только три варианта:
- Смените мерцание. (Я согласен, это не очень хороший вариант.)
- Используйте различные элементы управления, например стандартные, встроенные. Конечно, у них может не быть эффектного эффекта градиента, но это будет выглядеть сломанной половиной времени в любом случае, если пользователь настроил свою тему Windows. Также довольно сложно прочитать черный текст на темно-сером фоне.
- Измените код рисования внутри пользовательских элементов управления, чтобы сделать меньше работы. Вы можете пройти с помощью простых "оптимизаций", которые не будут стоить вам каких-либо визуальных эффектов, но я подозреваю, что это маловероятно. Это компромисс между скоростью и глазными конфетами. Не делать ничего всегда быстрее.