我一直在尝试为现有的.Net WinForms控件绘制自定义边框。我试图通过创建一个类来控制我想改变的边界颜色,然后在绘画时尝试几件事情。我试过以下内容:如何在.Net上绘制自定义边框WinForms控件
1. Catch WM_NCPAINT
。这有点。下面的代码的问题是,当控件调整大小时,边界将在右侧和底部切断。不好。
protected override void WndProc(ref Message m)
{
if (m.Msg == NativeMethods.WM_NCPAINT) {
WmNcPaint(ref m);
return;
}
base.WndProc(ref m);
}
private void WmNcPaint(ref Message m)
{
if (BorderStyle == BorderStyle.None) {
return;
}
IntPtr hDC = NativeMethods.GetWindowDC(m.HWnd);
if (hDC != IntPtr.Zero) {
using (Graphics g = Graphics.FromHdc(hDC)) {
ControlPaint.DrawBorder(g, new Rectangle(0, 0, this.Width, this.Height), _BorderColor, ButtonBorderStyle.Solid);
}
m.Result = (IntPtr)1;
NativeMethods.ReleaseDC(m.HWnd, hDC);
}
}
2.覆盖void OnPaint
。这适用于一些控件,但不是全部。这也要求您将BorderStyle
设置为BorderStyle.None
,并且您必须手动清除油漆背景,否则在调整大小时将清除背景you get this。
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
ControlPaint.DrawBorder(e.Graphics, new Rectangle(0, 0, this.Width, this.Height), _BorderColor, ButtonBorderStyle.Solid);
}
3.重写void OnResize
和void OnPaint
(如在方法2)。通过这种方式,它可以很好地进行调整大小,但不能在面板启用AutoScroll
时进行调整,在这种情况下,它将在滚动时调整为look like this。如果我尝试使用WM_NCPAINT
绘制边框,Refresh()
不起作用。
protected override void OnResize(EventArgs eventargs)
{
base.OnResize(eventargs);
Refresh();
}
建议不止欢迎。我想知道什么最好这样做,对于多种类型的控件(我将不得不这样做多个默认的WinForms控件)。
我相信你之前听说过,但我诚实的建议是只使用WPF而不是WinFroms。除此之外,您对我这样做的祝福,以及我写的一个精心编写的问题+1。 – BradleyDotNET 2014-09-29 17:45:28
谢谢!是的,我之前听说过很多次:)我仍然需要找时间学习WPF,但是这个项目对于WinForms来说太深了,无法将它转换成WPF。也许在将来。 – Codecat 2014-09-29 17:48:10
保护覆盖无效onResize受到(EventArgs的EventArgs的) { base.OnResize(EventArgs的); 刷新(); } – houssam 2014-09-29 20:35:47