Проблема ручной покраски

У меня есть некоторые странные артефакты рисования, которые, я надеюсь, кто-то сможет помочь мне определить.

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

скриншот http://img509.imageshack.us/img509/5650/18740614.png

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

Однако, когда я медленно изменяю размер панели, внизу остаются красные линии, которые, как я ожидал, будут скрыты желтыми заливками. Код, который я использую, выглядит следующим образом:

// Construction
sidePanel.Paint += new PaintEventHandler(OnPaint);

private void OnPaint(object sender, System.Windows.Forms.PaintEventArgs e)
{
   Panel pb = sender as Panel;
   PaintControl(pb.Width, pb.Height, sender, e, true);
}

private static void PaintControl(int width, int height, object sender, PaintEventArgs e, bool sidebar)
{
    Rectangle baseRectangle = new Rectangle(0, 0, width -1, height-1);

    using (LinearGradientBrush gradientBrush = new LinearGradientBrush(baseRectangle, WizardBaseForm.StartColour, WizardBaseForm.EndColour, 90))
    {
        e.Graphics.Clear(Color.Yellow);
        e.Graphics.DrawRectangle(Pens.Red, baseRectangle);
        e.Graphics.FillRectangle(Brushes.Yellow, baseRectangle);  
    }
}

protected override void OnResize(EventArgs e)
{
   base.OnResize(e);
   this.Invalidate();
}

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


person Ian    schedule 25.08.2009    source источник


Ответы (2)


Я бы предложил создать свою собственную панель, вывести ее из панели и поместить в конструктор следующее:

  this.SetStyle(ControlStyles.AllPaintingInWmPaint 
              | ControlStyles.OptimizedDoubleBuffer
              | ControlStyles.ResizeRedraw 
              | ControlStyles.DoubleBuffer 
              | ControlStyles.UserPaint
              , true);
person Lloyd Powell    schedule 25.08.2009
comment
Справедливо. Работает как шарм. Я до сих пор не совсем понимаю, почему проявилась изначальная проблема? - person Ian; 25.08.2009
comment
Это потому, что когда вы изменяете размер, событие рисования не запускается. Так что вам нужно заставить его с помощью ResizeRedraw, остальные не являются обязательными, но помогают с улучшением по-своему. Мерцание вашей формы раньше было связано с тем, что вы устанавливали стиль для формы, а не для панели. Это забавный мир, мир ручной росписи! - person Lloyd Powell; 25.08.2009

Добавьте следующее в New (после InitializeComponents):

this.SetStyle(ControlStyles.ResizeRedraw, true);

Это необходимо для обеспечения рисования при изменении размера.

Есть несколько дополнительных стилей, которые вы можете попробовать (AllPaintingInWmPaint, UserPaint...), но нужно ли их устанавливать или нет, зависит от вашего конкретного случая и от того, что именно вы хотите сделать. В случае, если все рисование выполняется вами в событии Paint, я бы установил их.

person Josip Medved    schedule 25.08.2009
comment
Иосип. Если я добавлю это, то вся форма будет мерцать, когда я начну изменять размер вещей... - person Ian; 25.08.2009
comment
Вам нужно добавить их только для панели. - person Lloyd Powell; 25.08.2009