Change border color in TextBox C#

前端 未结 4 1983
面向向阳花
面向向阳花 2020-11-28 10:42

I have the following code:

public class OurTextBox : TextBox
{
    public OurTextBox()
        : base()
    {
        this.SetStyle(ControlStyles.UserPaint,          


        
4条回答
  •  悲&欢浪女
    2020-11-28 11:33

    To change border color of TextBox you can override WndProc method and handle WM_NCPAINT message. Then get the window device context of the control using GetWindowDC because we want to draw to non-client area of control. Then to draw, it's enough to create a Graphics object from that context, then draw border for control.

    To redraw the control when the BorderColor property changes, you can use RedrawWindow method.

    Code

    Here is a TextBox which has a BorderColor property. The control uses BorderColor if the property values is different than Color.Transparent and BorderStyle is its default value 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:

    • Download Zip
    • Github repository

提交回复
热议问题