c# RichTextBox 边框颜色
c# RichTextBox Border Color
我正在尝试创建带有边框颜色的自定义 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);
}
}
这有什么问题?
参考MSDN article:
Overriding OnPaint will not allow you to modify the appearance of all controls. Those controls that have all of their painting done by Windows (for example, TextBox) never call their OnPaint method, and thus will never use the custom code. Refer to the Help documentation for the particular control you want to modify to see if the OnPaint method is available. For a list of all the Windows Form Controls, see Controls to Use on Windows Forms. If a control does not have OnPaint listed as a member method, you cannot alter its appearance by overriding this method. For more information about custom painting, see Custom Control Painting and Rendering.
但是有一个"hack",可以通过调用下面的代码实现调用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; }
}
来源:RichTextBox and UserPaint
另一点是你不能在 Rectangle 之外绘制(这是你的 RichTB 组件的总大小。所以你实际上想为他提供不同的坐标(较小的内部坐标)并且你会画到外面。
您的 class 看起来像:
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 更改,您将获得 "not nice" 有关绘图更改(如边框、新元素等)的行为。如果您想使用此类元素, 考虑使用 WPF - Windows Presentation Foundation。它们更适合模板化项目和修改设计。
回答晚了一点,但这些天我和你在同一条路上,它让我找到了这个解决方案,它对我有用:
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();
}
}
}
此富文本框更改了 3 种边框颜色 - 启用、聚焦和禁用以及禁用背景。如您所见,代码简单而简短。唯一的技巧是覆盖 KILL_FOCUS 和 EM_SETBKGNDCOLOR 消息(这个消息用于更改禁用的背景),RichTextbox 应该是 BorderStyle=None。干杯!
我正在尝试创建带有边框颜色的自定义 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);
}
}
这有什么问题?
参考MSDN article:
Overriding OnPaint will not allow you to modify the appearance of all controls. Those controls that have all of their painting done by Windows (for example, TextBox) never call their OnPaint method, and thus will never use the custom code. Refer to the Help documentation for the particular control you want to modify to see if the OnPaint method is available. For a list of all the Windows Form Controls, see Controls to Use on Windows Forms. If a control does not have OnPaint listed as a member method, you cannot alter its appearance by overriding this method. For more information about custom painting, see Custom Control Painting and Rendering.
但是有一个"hack",可以通过调用下面的代码实现调用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; }
}
来源:RichTextBox and UserPaint
另一点是你不能在 Rectangle 之外绘制(这是你的 RichTB 组件的总大小。所以你实际上想为他提供不同的坐标(较小的内部坐标)并且你会画到外面。
您的 class 看起来像:
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 更改,您将获得 "not nice" 有关绘图更改(如边框、新元素等)的行为。如果您想使用此类元素, 考虑使用 WPF - Windows Presentation Foundation。它们更适合模板化项目和修改设计。
回答晚了一点,但这些天我和你在同一条路上,它让我找到了这个解决方案,它对我有用:
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();
}
}
}
此富文本框更改了 3 种边框颜色 - 启用、聚焦和禁用以及禁用背景。如您所见,代码简单而简短。唯一的技巧是覆盖 KILL_FOCUS 和 EM_SETBKGNDCOLOR 消息(这个消息用于更改禁用的背景),RichTextbox 应该是 BorderStyle=None。干杯!