如何使用自定义颜色为MaskedTextBox绘制边框

本文关键字:MaskedTextBox 绘制 边框 颜色 何使用 自定义 | 更新日期: 2023-09-27 18:06:22

我想创建一个有边框颜色的蒙版文本框。

我尝试了下面的代码来实现它:

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

但问题是它没有遮罩文本框的所有功能,如设置遮罩类型等。

所以我把代码改成这样:
public class MaskedTextBoxWithBorder : UserControl

现在我有遮罩文本框的所有功能,但边框颜色不受影响。

是否有任何方法可以扩展蒙版文本框以获得边框样式,而不会失去像这样的功能,这是不可能的。

public class MaskedTextBoxWithBorder : UserControl, MaskedTestBox

如何使用自定义颜色为MaskedTextBox绘制边框

要绘制MaskedTextBox的边框,您应该覆盖WndProc并处理WM_NCPAINT消息。然后获取控件的窗口dc并从该dc创建Graphics对象,然后为控件绘制边界。该解决方案也在ToolStripTextBox中使用。该解决方案也可以应用于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);
        }
    }
}

TextBox和MaskedTextBox控件只是Win32 TextBox控件的包装器,因此所有者绘制它们(用于自定义边框,覆盖或其他任何东西)比通常情况下要复杂一点。以下是你应该做的,以达到你想要做的。

  1. 派生自MaskedTextBox: public class MaskedTextBoxWithBorder : MaskedTextBox
  2. 获取Win32 TextBox的消息流(它在响应多个消息时绘制自己,因此您需要捕获所有消息,而不仅仅是标准的WM_PAINT消息)。
  3. 获取设备上下文的句柄,并将其转换为一个托管图形对象来绘制边界。

看一下下面的文章,详细解释了每一步:向文本框或组合框添加图标或控件

尽管本文讨论的是基本的TextBox控件,但这并不重要。TextBox和MaskedTextBox都派生自TextBoxBase类,它实现了我们感兴趣的所有重要部分。

通常在给定的应用程序中,您只更改几个属性,因此您可以简单地为您的用户控件添加一些您希望能够更改的属性。

public class MaskedTextBoxWithBorder : UserControl
{
    MaskedTextBox maskedtextBox;
    // Other existing code...
    public string Mask
    {
        get { return maskedtextBox.Mask; }
        set { maskedtextBox.Mask = value; }
    }
    // Do same thing for other properties you want to change...
}

如果你真的想改变很多属性,那么其他的解决方案可能更合适…