在TextBox C#中更改边框颜色

Moi*_*nez 7 .net c# textbox winforms

我有以下代码:

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);
   }
}
Run Code Online (Sandbox Code Playgroud)

这是完美的,但它没有显示文本,直到它得到焦点.

有谁能够帮我?怎么了?

预先感谢.

Rez*_*aei 28

要更改边框颜色,TextBox可以覆盖WndProc方法和处理WM_NCPAINT消息.然后获取控件的窗口设备上下文,GetWindowDC因为我们想要绘制到非客户端控件区域.然后绘制,就足以Graphics从该上下文创建一个对象,然后绘制边框以进行控制.

要在BorderColor属性更改时重绘控件,可以使用RedrawWindow方法.

这是TextBox一个BorderColor有财产的.BorderColor如果属性值不同于Color.Transparent并且BorderStyle是其默认值,则控件使用Fixed3d.

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
Run Code Online (Sandbox Code Playgroud)
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);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果

这是使用不同颜色和不同状态的结果.支持所有边框样式的状态,如下图所示,您可以使用任何颜色作为边框:

在此输入图像描述

下载

您可以克隆或下载工作示例:

  • @ user3700562 我目前无法访问 Win7。一旦我有时间设置 Win7 VM,我就会看看。但是在 Win 8.1 和 10 上它运行正常。 (2认同)
  • @stuzor 你得到一条细白线的原因是因为具有固定 3D 边框的文本框的非客户区域是一个两个像素厚的矩形。要处理背景色问题,只需将上述代码的核心更改为: var hdc = GetWindowDC(this.Handle); 使用 (var g = Graphics.FromHdcInternal(hdc)) { 使用 (var p = new Pen(BorderColor)) g.DrawRectangle(p, new 矩形(0, 0, 宽度 - 1, 高度 - 1)); 使用 (var b = new Pen(BackColor)) g.DrawRectangle(b, new Rectangle(1, 1, 宽度 - 3, 高度 - 3)); ReleaseDC(this.Handle, hdc); (2认同)

gza*_*axx 5

您还必须手动绘制文本.

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);
}
Run Code Online (Sandbox Code Playgroud)

或者你可以尝试使用e.Graphics.DrawString()方法,如果TextRenderer没有给你想要的结果(我总是用这种方法有更好的结果).

  • 你不应该覆盖`OnPaint`,因为你需要绘制字符串,闪烁插入符号,选择突出显示等等.相反,您应该在`WndProc`中处理`WM_NCPAINT`消息并在非客户区域绘制边框,如[this](http://stackoverflow.com/questions/17466067/change-border-color-in-textbox-c -sharp/39420512#39420512). (3认同)