Унаследованный GroupBox имеет дрожание OnPaint

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

Когда я получаю от GroupBox и переопределяю функцию onPaint, групповые ящики перерисовываются поверх предыдущих групповых ящиков. Дочерний элемент правильно управляет рисованием, затрагивается только групповой ящик ..

Снимок экрана

class ExtendedComponents
{
  public partial class extendedGroupBox : GroupBox
  {
    private Color borderColor;

    public extendedGroupBox()
    {
      this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.ContainerControl, true);
      this.borderColor = Color.Black;
    }

    [NotifyParentProperty(true)]
    public Color BorderColor
    {
      get { return this.borderColor; }
      set { this.borderColor = value; Invalidate(); }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
      Size tSize = TextRenderer.MeasureText(this.Text, this.Font);

      Rectangle borderRect = e.ClipRectangle;
      borderRect.Y += tSize.Height / 2;
      borderRect.Height -= tSize.Height / 2;
      ControlPaint.DrawBorder(e.Graphics, borderRect, this.borderColor, ButtonBorderStyle.Dotted);

      Rectangle textRect = e.ClipRectangle;
      textRect.X += 6;
      textRect.Width = tSize.Width + 5;
      textRect.Height = tSize.Height;
      e.Graphics.FillRectangle(new SolidBrush(this.BackColor), textRect);
      e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), textRect);
    }
  }
}

Любая помощь приветствуется!


person Hutch    schedule 01.12.2011    source источник


Ответы (2)


Простой ответ - не использовать элемент управления GroupBox - он по своей сути динамичный.

Попробуйте использовать элемент управления Panel вместо DoubleBuffer SetStyles и т. Д.

Для вашей текущей реализации не используйте e.ClipRectangle:

//Rectangle borderRect = e.ClipRectangle;
Rectangle borderRect = this.ClientRectangle;

//Rectangle textRect = e.ClipRectangle;
Rectangle textRect = this.ClientRectangle;
person LarsTech    schedule 01.12.2011
comment
this.ClientRectangle недействителен, но я решил вместо этого воспользоваться вашей идеей управления панелью. Спасибо! - person Hutch; 02.12.2011
comment
@Hutch Рад, что ты можешь им пользоваться. Не уверен, почему this.ClientRectangle недействителен. Я использовал ваш код и заменил e.ClipRectangles на this.ClientRectangles, и забавные рисунки исчезли. - person LarsTech; 02.12.2011

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

person aquaherd    schedule 01.12.2011