Search code examples
c#winformsmaskedtextbox

How to draw border for MaskedTextBox using custom color?


I am trying to create a masked textbox to have a border colors.

I tried this below code to achieve it:

public class MaskedTextBoxWithBorder : UserControl
{
    MaskedTextBox maskedtextBox;

    public MaskedTextBoxWithBorder()
    {
        maskedtextBox = new MaskedTextBox()
        {
            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(maskedtextBox);
        this.Controls.Add(container);

        DefaultBorderColor = SystemColors.ControlDark;
        FocusedBorderColor = Color.Red;
        BackColor = DefaultBorderColor;
        Padding = new Padding(1);
        Size = maskedtextBox.Size;
    }

    public Color DefaultBorderColor { get; set; }
    public Color FocusedBorderColor { get; set; }

    public override string Text
    {
        get
        {
            return maskedtextBox.Text;
        }
        set
        {
            maskedtextBox.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, maskedtextBox.PreferredHeight, specified);
    }
}

But the problem is it does not have the all features of the masked text box like setting mask type etc.

So I changed my code like this:

public class MaskedTextBoxWithBorder : UserControl

Now I have all features of Masked text box but border colors are not affected.

Is there any way to extend Masked textbox to get border style without losing features something like this which is not possible.

public class MaskedTextBoxWithBorder : UserControl, MaskedTestBox

Solution

  • To draw border of MaskedTextBox you should override WndProc and handle WM_NCPAINT message. Then get the window dc of the control and create a Graphics object from that dc, then draw border for control.This solution has been used also in ToolStripTextBox. The solution can be applied also on a TextBox.

    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    public class MyMaskedTextBox : MaskedTextBox
    {
        public const int WM_NCPAINT = 0x85;
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);
        [DllImport("user32.dll")]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == WM_NCPAINT)
            {
                var hdc = GetWindowDC(this.Handle);
                using (var g = Graphics.FromHdcInternal(hdc))
                {
                    g.DrawRectangle(Pens.Blue, new Rectangle(0, 0, Width - 1, Height - 1));
                }
                ReleaseDC(this.Handle, hdc);
            }
        }
    }