2013-11-21 9 views
1

У меня есть настраиваемая панель, предназначенная для отображения сплошного цвета фона, цвета фона градиента или изображения.Застрял в петле OnPaint с настраиваемым элементом управления, полученным с панели

Я переопределены как свойство BackgroundImage и метод OnPaint так:

protected override void OnPaint(PaintEventArgs pe){ 
    Rectangle rc = new Rectangle(0, 0, this.Width, this.Height); 
    if (this.DrawStyle != DrawStyle.Picture){ 
     base.BackgroundImage = null; 

      if (this.DrawStyle == DrawStyle.Solid){ 
       using (SolidBrush brush = new SolidBrush(this.PrimaryColor)) 
        pe.Graphics.FillRectangle(brush, rc); 
      } 
      else if (this.DrawStyle == DrawStyle.Gradient){ 
       using (LinearGradientBrush brush = 
         new LinearGradientBrush(
          rc, this.PrimaryColor, this.SecondaryColor, this.Angle)) 
       pe.Graphics.FillRectangle(brush, rc); 
      } 
     } 
    else if (this._BGImage != null) 
     base.BackgroundImage = this._BGImage; 
} 

public override Image BackgroundImage{ 
    get { return this._BGImage; } 
    set { this._BGImage = value; } 
} 

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

Однако у меня проблема.

Если я не устанавливаю фоновое изображение, проблем нет. OnPaint вызывается примерно 5 раз, а затем все идет нормально.

Однако, когда я устанавливаю фоновое изображение, он, кажется, сходит с ума, снова и снова называет OnPaint снова и снова.

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

Так что, я думаю, вопрос у меня есть, почему он застревает в этом цикле OnPaint, когда я устанавливаю фоновое изображение?

+0

Я перевернул сообщение обратно на исходный вопрос, так как последние обновления удалили фактический вопрос. – LarsTech

ответ

2

Закомментируйте это:

// base.BackgroundImage = this._BGImage; 

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

Кроме того, вы ничего не делаете, переопределяя BackgroundImage, и если вы переопределяете свойство, это должно быть единственное место, где вы назначаете base.BackgroundImage значение. Подумайте об этом.

Я переработан код для этого:

protected override void OnPaintBackground(PaintEventArgs e) { 
    if (this.DrawStyle == DrawStyle.Picture) { 
    base.OnPaintBackground(e); 
    } 
} 

protected override void OnPaint(PaintEventArgs e) { 
    Rectangle rc = this.ClientRectangle; 
    if (this.DrawStyle == DrawStyle.Solid) { 
    using (SolidBrush brush = new SolidBrush(this.PrimaryColor)) 
     e.Graphics.FillRectangle(brush, rc); 
    } else if (this.DrawStyle == DrawStyle.Gradient) { 
    using (LinearGradientBrush brush = 
      new LinearGradientBrush(
       rc, this.PrimaryColor, this.SecondaryColor, this.Angle)) 
     e.Graphics.FillRectangle(brush, rc); 
    } 
    base.OnPaint(e); 
} 

Убедитесь, чтобы добавить this.DoubleBuffered = true; и this.ResizeRedraw = true; в конструкторе вашей панели, чтобы избежать ненужного мерцания.

+0

Хорошо спасибо. Я нашел обходное решение. Отредактировано с учетом изменений. – Will

+0

@ Я не буду делать это 'base.BackgroundImage = null;' в вашем вызове рисования. – LarsTech

+0

Можете ли вы просто сказать парню, чтобы он назначил base.BackgroundImage в своем сетевом устройстве? –