【发布时间】:2012-03-19 11:00:14
【问题描述】:
当用户点击或关注文本框时,如何更改文本框的边框颜色?
【问题讨论】:
-
如果您正在寻找具有
BorderColor属性的TextBox,请查看Change border color in TextBox
标签: c# .net winforms textbox border
当用户点击或关注文本框时,如何更改文本框的边框颜色?
【问题讨论】:
BorderColor 属性的TextBox,请查看Change border color in TextBox
标签: c# .net winforms textbox border
如果控件有焦点,您可以处理TextBox 的WM_NCPAINT 消息并在控件的非客户区绘制边框。您可以使用任何颜色来绘制边框:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class ExTextBox : TextBox
{
[DllImport("user32")]
private static extern IntPtr GetWindowDC(IntPtr hwnd);
private const int WM_NCPAINT = 0x85;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCPAINT && this.Focused)
{
var dc = GetWindowDC(Handle);
using (Graphics g = Graphics.FromHdc(dc))
{
g.DrawRectangle(Pens.Red, 0, 0, Width - 1, Height - 1);
}
}
}
}
结果
控件聚焦时的边框绘制完全无闪烁:
TextBox 的 BorderColor 属性
在当前帖子中,我只是更改焦点上的边框颜色。您还可以将BorderColor 属性添加到控件。然后您可以在设计时或运行时根据您的要求更改边框颜色。我发布了一个更完整的TextBox 版本,它具有BorderColor 属性:
在以下帖子中:
【讨论】:
试试这个
bool focus = false;
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (focus)
{
textBox1.BorderStyle = BorderStyle.None;
Pen p = new Pen(Color.Red);
Graphics g = e.Graphics;
int variance = 3;
g.DrawRectangle(p, new Rectangle(textBox1.Location.X - variance, textBox1.Location.Y - variance, textBox1.Width + variance, textBox1.Height +variance ));
}
else
{
textBox1.BorderStyle = BorderStyle.FixedSingle;
}
}
private void textBox1_Enter(object sender, EventArgs e)
{
focus = true;
this.Refresh();
}
private void textBox1_Leave(object sender, EventArgs e)
{
focus = false;
this.Refresh();
}
【讨论】:
Form1_Paint 上放置一个断点。现在,在 Form1 上绘制的每个控件的边框都围绕textBox1 绘制。最好创建一个从 TextBox 继承的自定义控件,以确保在需要时只绘制一次边框。而不是画很多次,这是不必要的,并大大增加了渲染时间。尤其是像这样的更多自定义上漆作业。
这是设置TextBox边框颜色的终极解决方案:
public class BorderedTextBox : UserControl
{
TextBox textBox;
public BorderedTextBox()
{
textBox = new TextBox()
{
BorderStyle = BorderStyle.FixedSingle,
Location = new Point(-1, -1),
Anchor = AnchorStyles.Top | AnchorStyles.Bottom |
AnchorStyles.Left | AnchorStyles.Right
};
Control container = new ContainerControl()
{
Dock = DockStyle.Fill,
Padding = new Padding(-1)
};
container.Controls.Add(textBox);
this.Controls.Add(container);
DefaultBorderColor = SystemColors.ControlDark;
FocusedBorderColor = Color.Red;
BackColor = DefaultBorderColor;
Padding = new Padding(1);
Size = textBox.Size;
}
public Color DefaultBorderColor { get; set; }
public Color FocusedBorderColor { get; set; }
public override string Text
{
get { return textBox.Text; }
set { textBox.Text = value; }
}
protected override void OnEnter(EventArgs e)
{
BackColor = FocusedBorderColor;
base.OnEnter(e);
}
protected override void OnLeave(EventArgs e)
{
BackColor = DefaultBorderColor;
base.OnLeave(e);
}
protected override void SetBoundsCore(int x, int y,
int width, int height, BoundsSpecified specified)
{
base.SetBoundsCore(x, y, width, textBox.PreferredHeight, specified);
}
}
【讨论】:
WinForms 从来不擅长这个,这有点痛苦。
您可以尝试的一种方法是在面板中嵌入一个文本框,然后从那里根据焦点管理绘图:
public class BorderTextBox : Panel {
private Color _NormalBorderColor = Color.Gray;
private Color _FocusBorderColor = Color.Blue;
public TextBox EditBox;
public BorderTextBox() {
this.DoubleBuffered = true;
this.Padding = new Padding(2);
EditBox = new TextBox();
EditBox.AutoSize = false;
EditBox.BorderStyle = BorderStyle.None;
EditBox.Dock = DockStyle.Fill;
EditBox.Enter += new EventHandler(EditBox_Refresh);
EditBox.Leave += new EventHandler(EditBox_Refresh);
EditBox.Resize += new EventHandler(EditBox_Refresh);
this.Controls.Add(EditBox);
}
private void EditBox_Refresh(object sender, EventArgs e) {
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.Clear(SystemColors.Window);
using (Pen borderPen = new Pen(this.EditBox.Focused ? _FocusBorderColor : _NormalBorderColor)) {
e.Graphics.DrawRectangle(borderPen, new Rectangle(0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1));
}
base.OnPaint(e);
}
}
【讨论】:
使用OnPaint 在控件上绘制自定义边框很好。但是知道如何使用OnPaint 来保持效率,并将渲染时间降到最低。如果您在使用自定义绘制例程时遇到延迟的 GUI,请阅读此内容:What is the right way to use OnPaint in .Net applications?
因为 PraVn 的公认答案看似简单,但实际上效率低下。使用自定义控件,就像上面答案中发布的那样更好。
也许性能在您的应用程序中不是问题,因为它很小,但对于具有大量自定义 OnPaint 例程的大型应用程序,使用 PraVn 显示的方式是错误的方法。
【讨论】:
将文本框边框样式设置为无 然后将此代码写入容器表单“绘制”事件
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);
}
【讨论】:
With PictureBox1
.Visible = False
.Width = TextBox1.Width + 4
.Height = TextBox1.Height + 4
.Left = TextBox1.Left - 2
.Top = TextBox1.Top - 2
.SendToBack()
.Visible = True
End With
【讨论】:
是不是很简单,
txtbox1.BorderColor = System.Drawing.Color.Red;
【讨论】: