我正在尝试为我的文本框创建一个自定义onPaint,它正在工作... it is working但是当我尝试输入内容时,a textbox is rendering above the textbox。
这是我的构造函数:
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
,我在这里有2个解决方案:
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);
}
}
这是文本框快照:FillRegion
的Graphics
方法用各种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);
}
}
这是文本框快照: