在 TextBox C# 中更改边框颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17466067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change border color in TextBox C#
提问by Moisés Martínez
I have the following code:
我有以下代码:
public class OurTextBox : TextBox
{
public OurTextBox()
: base()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Pen penBorder = new Pen(Color.Gray, 1);
Rectangle rectBorder = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1);
e.Graphics.DrawRectangle(penBorder, rectBorder);
}
}
This is working perfect, but it doesn't show the text until it gets focus.
这是完美的,但它不会显示文本,直到它获得焦点。
Can anybody help me? What is wrong?
有谁能够帮助我?怎么了?
Thank in advance.
预先感谢。
采纳答案by gzaxx
You have to draw text manually as well.
您还必须手动绘制文本。
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Pen penBorder = new Pen(Color.Gray, 1);
Rectangle rectBorder = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1);
e.Graphics.DrawRectangle(penBorder, rectBorder);
Rectangle textRec = new Rectangle(e.ClipRectangle.X + 1, e.ClipRectangle.Y + 1, e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1);
TextRenderer.DrawText(e.Graphics, Text, this.Font, textRec, this.ForeColor, this.BackColor, TextFormatFlags.Default);
}
Alternatively you can try to use e.Graphics.DrawString()method if TextRendereris not giving you desired results (I always have better results with this approach thou).
或者,e.Graphics.DrawString()如果TextRenderer没有给您想要的结果,您可以尝试使用方法(我总是用这种方法获得更好的结果)。
回答by MoonKnight
There are several ways to do this and none are ideal. This is just the nature of WinForms. However, you have some options. I will summarise:
有几种方法可以做到这一点,但没有一种是理想的。这正是 WinForms 的特性。但是,您有一些选择。我总结一下:
One way you can achieve what you want is by embedding a TextBoxin a Panelas follows.
您可以实现所需的一种方法是将 a 嵌入TextBox到 a 中Panel,如下所示。
public class BorderedTextBox : Panel
{
private TextBox textBox;
private bool focusedAlways = false;
private Color normalBorderColor = Color.Gray;
private Color focusedBorderColor = Color.Red;
public BorderTextBox()
{
this.DoubleBuffered = true;
this.Padding = new Padding(2);
this.TextBox = new TextBox();
this.TextBox.AutoSize = false;
this.TextBox.BorderStyle = BorderStyle.None;
this.TextBox.Dock = DockStyle.Fill;
this.TextBox.Enter += new EventHandler(this.TextBox_Refresh);
this.TextBox.Leave += new EventHandler(this.TextBox_Refresh);
this.TextBox.Resize += new EventHandler(this.TextBox_Refresh);
this.Controls.Add(this.TextBox);
}
private void TextBox_Refresh(object sender, EventArgs e)
{
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.Clear(SystemColors.Window);
using (Pen borderPen = new Pen(this.TextBox.Focused || FocusedAlways ?
focusedBorderColor : normalBorderColor))
{
e.Graphics.DrawRectangle(borderPen,
new Rectangle(0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1));
}
base.OnPaint(e);
}
public TextBox TextBox
{
get { return textbox; }
set { textbox = value; }
}
public bool FocusedAlaways
{
get { return focusedAlways; }
set { focusedAlways = value; }
}
}
You can also do this without overriding any controls, but the above method is better. The above will draw a border when the control gets focus. if you want the border on permanently, set the FocusedAlwaysproperty to True.
您也可以在不覆盖任何控件的情况下执行此操作,但上述方法更好。当控件获得焦点时,上面将绘制一个边框。如果您希望边框永久打开,请将FocusedAlways属性设置为True。
I hope this helps.
我希望这有帮助。
回答by Moory Pc
set Text box Border style to None then write this code to container form "paint" event
将文本框边框样式设置为无,然后将此代码写入容器表单“绘制”事件
private void Form1_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Rectangle rect = new Rectangle(TextBox1.Location.X, TextBox1.Location.Y, TextBox1.ClientSize.Width, TextBox1.ClientSize.Height);
rect.Inflate(1, 1); // border thickness
System.Windows.Forms.ControlPaint.DrawBorder(e.Graphics, rect, Color.DeepSkyBlue, ButtonBorderStyle.Solid);
}
回答by Reza Aghaei
To change border color of TextBoxyou can override WndProcmethod and handle WM_NCPAINTmessage. Then get the window device context of the control using GetWindowDCbecause we want to draw to non-client area of control. Then to draw, it's enough to create a Graphicsobject from that context, then draw border for control.
要更改边框颜色,TextBox您可以覆盖WndProc方法并处理WM_NCPAINT消息。然后获取控件的窗口设备上下文,GetWindowDC因为我们要绘制到控件的非客户区。然后要绘制,Graphics从该上下文创建一个对象就足够了,然后绘制边框进行控制。
To redraw the control when the BorderColorproperty changes, you can use RedrawWindowmethod.
要在BorderColor属性更改时重绘控件,可以使用RedrawWindow方法。
Code
代码
Here is a TextBoxwhich has a BorderColorproperty. The control uses BorderColorif the property values is different than Color.Transparentand BorderStyleis its default value Fixed3d.
这是一个TextBox有BorderColor属性的。BorderColor如果属性值不同于Color.Transparent并且BorderStyle是其默认值,则控件使用Fixed3d。
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class MyTextBox : TextBox {
const int WM_NCPAINT = 0x85;
const uint RDW_INVALIDATE = 0x1;
const uint RDW_IUPDATENOW = 0x100;
const uint RDW_FRAME = 0x400;
[DllImport("user32.dll")]
static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll")]
static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprc, IntPtr hrgn, uint flags);
Color borderColor = Color.Blue;
public Color BorderColor {
get { return borderColor; }
set { borderColor = value;
RedrawWindow(Handle, IntPtr.Zero, IntPtr.Zero,
RDW_FRAME | RDW_IUPDATENOW | RDW_INVALIDATE);
}
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == WM_NCPAINT && BorderColor != Color.Transparent &&
BorderStyle == System.Windows.Forms.BorderStyle.Fixed3D) {
var hdc = GetWindowDC(this.Handle);
using (var g = Graphics.FromHdcInternal(hdc))
using (var p = new Pen(BorderColor))
g.DrawRectangle(p, new Rectangle(0, 0, Width - 1, Height - 1));
ReleaseDC(this.Handle, hdc);
}
}
protected override void OnSizeChanged(EventArgs e) {
base.OnSizeChanged(e);
RedrawWindow(Handle, IntPtr.Zero, IntPtr.Zero,
RDW_FRAME | RDW_IUPDATENOW | RDW_INVALIDATE);
}
}
Result
结果
Here is the result using different colors and different states. All states of border-style is supported as you can see in below image and you can use any color for border:
这是使用不同颜色和不同状态的结果。支持所有边框样式状态,如下图所示,您可以使用任何颜色的边框:
Download
下载
You can clone or download the working example:
您可以克隆或下载工作示例:


