2016-04-22 3 views
1

Я создал класс GradientButton, который предположительно будет кнопкой, заполненной градиентным фоном.Метод OnPaintBackground никогда не вызывается для управления, полученного из Button

Я рисую градиентное заполнение в методе OnPaintBackground(). К сожалению, он никогда не вызывается, конечно, я добавил GradientButton к Form через панель инструментов:

public class GradientButton : Button { 

     public Color Color1 { get; set; } 
     public Color Color2 { get; set; } 

     public float Angle { get; set; } 

     public GradientButton() { 
      Color1 = Color.YellowGreen; 
      Color2 = Color.LightGreen; 
      Angle = 30; 
     } 



     protected override void OnPaintBackground(PaintEventArgs e) { 
      base.OnPaintBackground(e); 
      Debug.WriteLine("This never prints"); 
      using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle, 
                     Color1, 
                     Color2, 
                     Angle)) { 
       e.Graphics.FillRectangle(brush, this.ClientRectangle); 
      } 
     } 
     protected override void OnResize(EventArgs e) { 
      base.OnResize(e); 
      Invalidate(); 
     } 
    } 

Вопрос: Как заполнить фон баттона с градиентом? Почему OnPaintBackground не вызывается? Насколько мне известно, его следует называть до OnPaint.

+0

Обычно это вызвано WM_ERASEBKGND, но это сообщение получает [специальное обращение] (http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Button.cs,db879261d0cac688) в Button.WndProc(), минуя обычную обработку. Преимущество заключается в том, что не требуется двойной буферизации. Он не нужен, OnPaint() рисует все. Вы, в свою очередь, должны переопределить OnPaint(). –

ответ

-1

Я бы сделал это вместо этого.

Во-первых, изменить конструктор к этому:

public GradientButton() 
    { 
     Color1 = Color.YellowGreen; 
     Color2 = Color.LightGreen; 
     Angle = 30; 
     Paint += new PaintEventHandler(GradientButton_Paint); 
    } 

А затем добавьте ниже процедуру:

private void GradientButton_Paint(object sender,PaintEventArgs e) 
    { 
     Debug.WriteLine("This never prints"); 
     using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,Color1,Color2,Angle)) 
     { 
      e.Graphics.FillRectangle(brush, this.ClientRectangle); 
     } 
    } 

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

+0

Спасибо всем, кто подал вслух, отличный совет, который вы дали. – Rariolu

+0

Спасибо за ваши усилия. Есть две причины, по которым sb (не я) отклонил ваш ответ. Первый заключается в том, что предполагается переопределить метод «OnPaint», а не подписываться на событие.Во-вторых, это вызывает краску градиента над всем содержимым кнопки, поэтому текст невидим. – Yoda

+0

Я полагаю, что – Rariolu

0

Вы должны установить стиль формы в конструкторе ...

this.SetStyle(ControlStyles.UserPaint, true); 

обеспечить метод OnPaint переопределен. Есть много настроек для ControlStyle, которые можно комбинировать

2

Это происходит потому, что Button класс имеет ControlStyles.Opaque установлен флаг, который в соответствии с документацией:

Если это правда, то управление обращается непрозрачным и фон не окрашены.

Вы можете отключить его в вашем конструкторе класса

SetStyle(ControlStyles.Opaque, false); 

и ваш OnPaintBackground переопределение будет вызван.

Однако, это не помогло бы много - есть причина, флаг должен быть установлен в true - OnPaint рисует как фон и лицо кнопки, так что вы будете делать в OnPaintBackground не будет иметь никакого влияния на кнопку появление. К сожалению, нет возможности рисовать только фон, поэтому вам нужно переопределить OnPaint и на самом деле нарисовать все, что угодно.

+0

Проверял, понял, затем я создал «UserControl» с прозрачной кнопкой в ​​нем и нарисовал цвет «UserControl», и я думаю, что это самое простое решение, но верно ли это в вашей книге? – Yoda

+1

Ха, в моей книге говорится, что все, что работает, правильно :) Это может сработать, но, кроме того, чтобы установить кнопку 'BackColor' на' Color.Transparent', я думаю, вам также нужно будет установить FlatStyle на Flat и поставить некоторые alpha в 'FlatApprearance'' MouseDownBackColor' и' MouseOverBackColor'. –

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