文本框自定义onPaint

我正在尝试为我的文本框创建一个自定义onPaint,它正在工作…… 它正在工作但是当我尝试输入某些内容时, 文本框会在文本框上方呈现 。

这是我的构造函数:

public TextBox() { Font = new Font("Segoe UI", 11F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0))); BackColor = Color.White; BorderColor = Color.Gray; BorderStyle = BorderStyle.None; SetStyle(ControlStyles.UserPaint, true); } 

和onPaint:

 protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; g.FillRectangle(backgroundBrush, 0, 0, this.Width, this.Height); SizeF fontSize = g.MeasureString(Text, Font); g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF(5, 5), cFormat); g.DrawRectangle(borderPen, borderPen.Width / 2, borderPen.Width / 2, this.Width - borderPen.Width, this.Height - borderPen.Width); } 

如果你只想要一个带有一些自定义边框(宽度和颜色)的自定义TextBox ,我在这里有两个解决方案:

  1. 使用ControlPaint ,这将允许您绘制一些样式和颜色的边框,但不能使用Brush来更多地绘制(像HatchBrush可以做的):

     public class CustomTextBox : TextBox { [DllImport("user32")] private static extern IntPtr GetWindowDC(IntPtr hwnd); struct RECT { public int left, top, right, bottom; } struct NCCALSIZE_PARAMS { public RECT newWindow; public RECT oldWindow; public RECT clientWindow; IntPtr windowPos; } float clientPadding = 2; float actualBorderWidth = 4; Color borderColor = Color.Red; protected override void WndProc(ref Message m) { //We have to change the clientsize to make room for borders //if not, the border is limited in how thick it is. if (m.Msg == 0x83) //WM_NCCALCSIZE { if (m.WParam == IntPtr.Zero) { RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT)); rect.left += clientPadding; rect.right -= clientPadding; rect.top += clientPadding; rect.bottom -= clientPadding; Marshal.StructureToPtr(rect, m.LParam, false); } else { NCCALSIZE_PARAMS rects = (NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALSIZE_PARAMS)); rects.newWindow.left += clientPadding; rects.newWindow.right -= clientPadding; rects.newWindow.top += clientPadding; rects.newWindow.bottom -= clientPadding; Marshal.StructureToPtr(rects, m.LParam, false); } } if (m.Msg == 0x85) //WM_NCPAINT { IntPtr wDC = GetWindowDC(Handle); using(Graphics g = Graphics.FromHdc(wDC)){ ControlPaint.DrawBorder(g, new Rectangle(0,0,Size.Width, Size.Height), borderColor, actualBorderWidth, ButtonBorderStyle.Solid, borderColor, actualBorderWidth, ButtonBorderStyle.Solid, borderColor, actualBorderWidth, ButtonBorderStyle.Solid, borderColor, actualBorderWidth, ButtonBorderStyle.Solid); } return; } base.WndProc(ref m); } } 

    这是文本框快照:

  2. 使用Graphics FillRegion方法用各种Brush绘制边框,这里我使用HatchBrush

     public class CustomTextBox : TextBox { [DllImport("user32")] private static extern IntPtr GetWindowDC(IntPtr hwnd); struct RECT { public int left, top, right, bottom; } struct NCCALSIZE_PARAMS { public RECT newWindow; public RECT oldWindow; public RECT clientWindow; IntPtr windowPos; } int clientPadding = 2; int actualBorderWidth = 4; protected override void WndProc(ref Message m) { //We have to change the clientsize to make room for borders //if not, the border is limited in how thick it is. if (m.Msg == 0x83) //WM_NCCALCSIZE { if (m.WParam == IntPtr.Zero) { RECT rect = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT)); rect.left += clientPadding; rect.right -= clientPadding; rect.top += clientPadding; rect.bottom -= clientPadding; Marshal.StructureToPtr(rect, m.LParam, false); } else { NCCALSIZE_PARAMS rects = (NCCALSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALSIZE_PARAMS)); rects.newWindow.left += clientPadding; rects.newWindow.right -= clientPadding; rects.newWindow.top += clientPadding; rects.newWindow.bottom -= clientPadding; Marshal.StructureToPtr(rects, m.LParam, false); } } if (m.Msg == 0x85) //WM_NCPAINT { IntPtr wDC = GetWindowDC(Handle); using(Graphics g = Graphics.FromHdc(wDC)){ Rectangle rect = new Rectangle(0,0,Width,Height); Rectangle inner = new Rectangle(0, 0, Width, Height); inner.Offset(actualBorderWidth + 2, actualBorderWidth + 2); inner.Width -= 2 * actualBorderWidth + 4; inner.Height -= 2 * actualBorderWidth + 4; Region r = new Region(rect); r.Xor(inner); using (System.Drawing.Drawing2D.HatchBrush brush = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.SmallCheckerBoard, Color.Green, Color.Red)) { g.FillRegion(brush, r); } } return; } base.WndProc(ref m); } } 

    这是文本框快照:
    用滚动条