2017-01-27 5 views
1

Ich versuche, eine benutzerdefinierte RichTextBox mit Grenzfarbe zu schaffen, aber ich habe ein Problem ... Meine Grenze Farbe nichtC# RichTextBox Randfarbe

zeigt mein Code hier:

public partial class AlXRichTextBox : RichTextBox 
{ 
    private RichTextBox textBox; 

    private Color borderColor; 

    public AlXRichTextBox() 
    { 
     InitializeComponent(); 
    } 
    public Color BorderColor 
    { 
     get { return borderColor; } 
     set { borderColor = value; Invalidate(); } 
    } 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     Pen p = new Pen(borderColor); 
     Graphics g = e.Graphics; 
     int variance = 3; 
     //g.DrawRectangle(p, new Rectangle(base.Location.X - variance, base.Location.Y - variance, base.Width + variance, base.Height + variance)); 
     ControlPaint.DrawBorder(e.Graphics, base.ClientRectangle, borderColor, ButtonBorderStyle.Solid); 
    } 

    private void InitializeComponent() 
    { 
      this.textBox = new System.Windows.Forms.RichTextBox(); 
      this.SuspendLayout(); 
      // 
      // richTextBox1 
      // 
      this.textBox.Location = new System.Drawing.Point(0, 0); 
      this.textBox.Name = "richTextBox1"; 
      this.textBox.Size = new System.Drawing.Size(100, 96); 
      this.textBox.TabIndex = 0; 
      this.textBox.Text = ""; 
      this.textBox.Multiline = true; 
      this.textBox.BorderStyle = BorderStyle.None; 
      // 
      // AlXRichTextBox 
      // 
      this.Size = new System.Drawing.Size(278, 123); 
      this.ResumeLayout(false); 
    } 
} 

Was ist Problem mit diesem?

Antwort

1

Mit Bezug auf MSDN article:

Zwingende OnPaint wird nicht zulassen, dass Sie das Aussehen aller Kontrollen ändern. Diese Steuerelemente, die alle von Windows (z. B. TextBox) gezeichnet haben, rufen ihre OnPaint-Methode nie auf und werden daher den benutzerdefinierten Code nie verwenden. In der Hilfedokumentation für das bestimmte Steuerelement, das Sie ändern möchten, um zu sehen, ob die OnPaint-Methode verfügbar ist. Eine Liste aller Windows-Formularsteuerelemente finden Sie unter Steuerelemente zur Verwendung in Windows Forms. Wenn OnPaint für ein Steuerelement nicht als Mitgliedsmethode aufgeführt ist, können Sie die Darstellung nicht durch Überschreiben dieser Methode ändern. Weitere Informationen zum benutzerdefinierten Zeichnen finden Sie unter Anpassen und Rendern von benutzerdefinierten Steuerelementen.

Allerdings gibt es einen "Hack", können Sie erreichen das Paint-Methode aufrufen durch folgenden Code aufrufen:

private const int WM_PAINT = 15; 
protected override void WndProc(ref System.Windows.Forms.Message m) 
{ 
    base.WndProc(ref m); 
    if (m.Msg == WM_PAINT && !inhibitPaint) 
    { 
     // raise the paint event 
     using (Graphics graphic = base.CreateGraphics()) 
      OnPaint(new PaintEventArgs(graphic, 
      base.ClientRectangle)); 
    } 
    } 

    private bool inhibitPaint = false; 

    public bool InhibitPaint 
    { 
     set { inhibitPaint = value; } 
    } 

Src: RichTextBox and UserPaint

Andere Punkt ist, dass Sie nicht außerhalb des zeichnen Rechteck (das ist die Gesamtgröße Ihrer RichTB-Komponente. Sie möchten ihm also tatsächlich verschiedene Coords (kleinere innere) zur Verfügung stellen und Sie werden nach außen zeichnen.

Ihre Klasse wird wie folgt aussehen:

public partial class AlXRichTextBox : RichTextBox 
{ 
    private Color borderColor = Color.Red; 

    public Color BorderColor 
    { 
     get { return borderColor; } 
     set { borderColor = value; Invalidate(); } 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     int variance = 3; 
     e = new PaintEventArgs(e.Graphics, new Rectangle(e.ClipRectangle.X + variance, e.ClipRectangle.Y + variance, e.ClipRectangle.Width - variance, e.ClipRectangle.Height - variance)); 
     base.OnPaint(e); 

     Pen p = new Pen(borderColor, variance); 
     Graphics g = e.Graphics; 
     g.DrawRectangle(p, new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width, e.ClipRectangle.Height)); 
    } 


    private const int WM_PAINT = 15; 
    protected override void WndProc(ref System.Windows.Forms.Message m) 
    { 
     base.WndProc(ref m); 
     if (m.Msg == WM_PAINT && !inhibitPaint) 
     { 
      // raise the paint event 
      using (Graphics graphic = base.CreateGraphics()) 
       OnPaint(new PaintEventArgs(graphic, 
       base.ClientRectangle)); 
     } 

    } 

    private bool inhibitPaint = false; 

    public bool InhibitPaint 
    { 
     set { inhibitPaint = value; } 
    } 
} 

WICHTIG

Da es nicht für diese Kontrolle wird voraussichtlich von Paint geändert werden, werden Sie erhalten „nicht schön“ Verhalten in Bezug auf die Zeichnung, die Änderungen wie Grenze, Neue Elemente usw. Wenn Sie ein solches Element verwenden möchten, sollten Sie die Verwendung von WPF - Windows Presentation Foundation in Erwägung ziehen. Sie sind viel schöner, wenn es darum geht, die Gegenstände zu verändern und das Design zu verändern.

+0

Vielen Dank Sir, sehr nette Antwort – Al00X

0

Ein wenig spät Antwort, aber ich auf demselben Weg, wie Sie in diesen Tagen war und es hat mich zu dieser Lösung, Es funktioniert für mich:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

public class MyRichTextBox : RichTextBox 
{ 
    private const UInt32 WM_PAINT = 0x000F; 
    private const UInt32 WM_USER = 0x0400; 
    private const UInt32 EM_SETBKGNDCOLOR = (WM_USER + 67); 
    private const UInt32 WM_KILLFOCUS = 0x0008; 

    public MyRichTextBox() 
    { 
     this.BorderStyle = System.Windows.Forms.BorderStyle.None; 
    } 

    protected override void WndProc(ref System.Windows.Forms.Message m) 
    { 
     base.WndProc(ref m); 

     Graphics g = Graphics.FromHwnd(Handle); 
     Rectangle bounds = new Rectangle(0, 0, Width - 1, Height - 1); 
     Pen p = new Pen(SystemColors.Highlight, 3); 

     if (m.Msg == WM_PAINT) 
     { 
      if (this.Enabled == true) 
      { 

       if (this.Focused) 
       { 
        g.DrawRectangle(p, bounds); 
       } 

       else 
       { 
        g.DrawRectangle(SystemPens.ControlDark, bounds); 
       } 

      } 
      else 
      { 
       g.FillRectangle(Brushes.White, bounds); 
       g.DrawRectangle(SystemPens.Control, bounds); 
      } 
     } 

     if (m.Msg == EM_SETBKGNDCOLOR) //color disabled background 
     { 
      Invalidate(); 
     } 

     if (m.Msg == WM_KILLFOCUS) //set border back to normal on lost focus 
     { 
      Invalidate(); 
     } 
    } 

} 

Diese Rich Textbox 3 Randfarben ändert - aktiviert ist, fokussiert und mit deaktiviertem Hintergrund deaktiviert. Wie Sie sehen, ist der Code einfach und kurz. Der einzige Trick besteht darin, KILL_FOCUS- und EM_SETBKGNDCOLOR-Nachrichten zu überschreiben (dies dient zum Ändern des deaktivierten Hintergrunds), und RichTextbox sollte BorderStyle = None sein. Prost !