2017-01-27 7 views
1

Я пытаюсь создать пользовательский RichTextBox с цветом границы, но у меня есть проблема ... Мой цвет границы не показываяC# RichTextBox Цвет рамки

Вот мой код:

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

Что проблема с этим?

ответ

1

Ссылаясь на MSDN article:

переопределение OnPaint не позволит вам изменить внешний вид всех элементов управления. Те элементы управления, которые имеют всю свою картину, сделанные Windows (например, TextBox), никогда не вызывают их метод OnPaint и, следовательно, никогда не будут использовать настраиваемый код. Обратитесь к справочной документации для конкретного элемента управления, который вы хотите изменить, чтобы узнать, доступен ли метод OnPaint. Список всех элементов управления Windows Form см. В разделе Элементы управления для использования в Windows Forms. Если у элемента управления нет OnPaint, указанного как метод участника, вы не можете изменить его внешний вид, переопределив этот метод. Дополнительные сведения о пользовательской картине см. В разделе «Индивидуальная обработка изображений и рендеринга».

Однако есть «взломать», можно добиться, вызвав метод Paint, вызвав следующий код:

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

Другое дело в том, что Вы не можете сделать снаружи из Прямоугольник (который является общим размером вашего компонента RichTB, поэтому вы действительно хотите предоставить ему различные Coords (меньшие внутренние), и вы будете рисовать снаружи.

Ваш класс будет выглядеть следующим образом:

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

ВАЖНО

Как не ожидается, для этого элемента управления, чтобы быть изменен Paint, вы получите «не хороший» поведение в отношении изменений чертежа, как границы, новые элементы и т. д. Если вы хотите использовать такой элемент, подумайте об использовании WPF - Windows Presentation Foundation. Они намного приятнее шаблонизировать элементы и модифицировать дизайн.

+0

Thankyou Sir, Very Nice Answer – Al00X

0

Немного поздно ответ, но я был на том же пути, как вы в эти дни, и это заставило меня к этому решению, оно работает для меня:

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

} 

Это Рич Textbox изменяет 3 цвета границы - включен, сосредоточенный и отключен с отключенным фоном. Как видите, код прост и короток. Единственный трюк состоит в том, чтобы переопределить сообщения KILL_FOCUS и EM_SETBKGNDCOLOR (это для изменения фона с отключением), а RichTextbox должен быть BorderStyle = None. Приветствия!

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

  • Нет связанных вопросов^_^