【问题标题】:Change the borderColor of the TextBox更改文本框的边框颜色
【发布时间】:2012-03-19 11:00:14
【问题描述】:

当用户点击或关注文本框时,如何更改文本框的边框颜色?

【问题讨论】:

标签: c# .net winforms textbox border


【解决方案1】:

如果控件有焦点,您可以处理TextBoxWM_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 属性: 在以下帖子中:

【讨论】:

  • 当按钮的平面样式是标准的时,如何为按钮做同样的事情?我的意思是按钮在单击时会突出显示为蓝色。
【解决方案2】:

试试这个

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

【讨论】:

  • 谢谢,它确实有效,但它也改变了表单中所有其他文本框的边框颜色,你能解释一下它是如何发生的以及如何使颜色变为红色,它只有蓝色! !
  • 我不认为上面的代码会改变所有文本框的边框。我们正在做的是,我们在 textBox1 周围画一个矩形
  • 如何在边框或矩形周围应用不同的颜色
  • 我对@PraVn 代码做了一些更改,现在我认为它很漂亮:int variance = 1; g.DrawRectangle(p,new Rectangle(textBox1.Location.X - 方差,textBox1.Location.Y - 方差,textBox1.Width + 方差,textBox1.Height +方差));方差 = 2; g.DrawRectangle(p,new Rectangle(textBox1.Location.X - 方差,textBox1.Location.Y - 方差,textBox1.Width +variance+1,textBox1.Height +variance+1));
  • 当父控件中有更多控件时,在 OnPaint 中完成任何操作是一个坏主意。要亲自了解我的意思,请执行以下操作:在表单上放置 10 个控件,但在 Form1_Paint 上放置一个断点。现在,在 Form1 上绘制的每个控件的边框都围绕textBox1 绘制。最好创建一个从 TextBox 继承的自定义控件,以确保在需要时只绘制一次边框。而不是画很多次,这是不必要的,并大大增加了渲染时间。尤其是像这样的更多自定义上漆作业。
【解决方案3】:

这是设置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);
    }
}

【讨论】:

  • 我们可以让这个文本框多行吗?
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    使用OnPaint 在控件上绘制自定义边框很好。但是知道如何使用OnPaint 来保持效率,并将渲染时间降到最低。如果您在使用自定义绘制例程时遇到延迟的 GUI,请阅读此内容:What is the right way to use OnPaint in .Net applications?

    因为 PraVn 的公认答案看似简单,但实际上效率低下。使用自定义控件,就像上面答案中发布的那样更好。

    也许性能在您的应用程序中不是问题,因为它很小,但对于具有大量自定义 OnPaint 例程的大型应用程序,使用 PraVn 显示的方式是错误的方法。

    【讨论】:

      【解决方案6】:

      将文本框边框样式设置为无 然后将此代码写入容器表单“绘制”事件

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

      【讨论】:

        【解决方案7】:
        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
        

        【讨论】:

        • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
        【解决方案8】:

        是不是很简单,

        txtbox1.BorderColor = System.Drawing.Color.Red;

        【讨论】:

        • 你应该在建议之前先测试一下。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-09
        • 1970-01-01
        • 1970-01-01
        • 2011-03-27
        • 1970-01-01
        • 2017-03-05
        相关资源
        最近更新 更多