2016-04-22 9 views
1

abgeleitet wird. Ich habe eine Klasse GradientButton erstellt, bei der es sich um einen Button handelt, der mit Hintergrund mit Farbverlauf gefüllt ist.Die OnPaintBackground-Methode wird nie für das Steuerelement aufgerufen, das von Button

Ich zeichne Gradientenfüllung in der OnPaintBackground() Methode. Leider ist es nie aufgerufen, natürlich habe ich eine GradientButton zu einem Form über Toolbox:

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(); 
     } 
    } 

Frage:, wie der Hintergrund der Schaltfläche füllen mit dem Farbverlauf? Warum wird OnPaintBackground nicht aufgerufen? Soweit ich weiß, sollte es vor OnPaint Methode aufgerufen werden.

+0

Es wird normalerweise von WM_ERASEBKGND ausgelöst, aber diese Nachricht wird [spezielle Behandlung] (http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Button.cs,db879261d0cac688) in Button.WndProc(), unter Umgehung der normalen Handhabung. Der Vorteil ist, dass keine Doppelpufferung erforderlich ist. Es wird nicht benötigt, OnPaint() zeichnet alles. Sie müssen stattdessen OnPaint() überschreiben. –

Antwort

-1

Ich würde dies stattdessen tun.

Zum einem Konstruktor Um dies zu ändern:

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

Und dann die unten stehende Prozedur hinzu:

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); 
     } 
    } 

Ich bin nicht ganz sicher, warum Ihr Code nicht funktioniert, aber die Art und Weise Ich habe beschrieben, funktioniert immer für mich. Hoffe, das ist gut genug.

+0

Danke, wer auch immer downvoted, großer Ratschlag, den du gabst. – Rariolu

+0

Vielen Dank für Ihre Mühe. Es gibt zwei Gründe, warum sb (nicht ich) Ihre Antwort abgelehnt hat. Die erste ist, dass man die OnPaint-Methode außer Kraft setzt und das Ereignis nicht abonniert.Zweitens bewirkt dies, dass über den gesamten Inhalt der Schaltfläche ein Farbverlauf gezeichnet wird, so dass der Text unsichtbar ist. – Yoda

+0

Gut genug, nehme ich an – Rariolu

0

Sie müssen den Stil der Form in den Konstruktor setzen ...

this.SetStyle(ControlStyles.UserPaint, true); 

die OnPaint-Methode außer Kraft gesetzt, um sicherzustellen. Es gibt viele Einstellungen für die ControlStyle, die Sie

2

Dies liegt daran, die Button Klasse ControlStyles.Opaque Flag gesetzt kombinieren können, die nach der Dokumentation:

Wenn das stimmt, die Steuer undurchsichtigen gezogen wird und der Hintergrund ist nicht gemalt.

Sie können es drehen in der Klasse Konstruktor

SetStyle(ControlStyles.Opaque, false); 

und Ihre OnPaintBackground Überschreibung aufgerufen wird ausgeschaltet.

Allerdings sei es nicht viel helfen - es gibt einen Grund das Flag auf true gesetzt werden - die OnPaint zieht sowohl Hintergrund und Gesicht der Taste, so dass, was auch immer Sie in OnPaintBackground tun hat nichts von der Taste beeinflussen Aussehen. Leider gibt es keine Option, nur den Hintergrund zu malen, also müssen Sie die OnPaint überschreiben und tatsächlich alles selbst zeichnen.

+0

Überprüft, verstanden, dann habe ich 'UserControl' mit einem transparenten Knopf darin erstellt und' UserControl's' zurück Farbe gezeichnet und ich denke, es ist die einfachste Lösung, aber ist es richtig in Ihrem Buch? – Yoda

+1

Ha, mein Buch sagt alles, was funktioniert. :) Es könnte funktionieren, aber zusätzlich zum Setzen der Schaltfläche 'BackColor' auf' Color.Transparent' denke ich, dass du auch 'FlatStyle' auf' Flat' setzen und einige setzen musst Alpha in 'FlatAppreorance'' MouseDownBackColor' und 'MouseOverBackColor'. –