当覆盖自定义控件的OnPaint方法时,我提供了PaintEventArgs,其中包含Graphics对象和ClipRectangle。 ClipRectangle太小了,不适合我的口味,因此我想要将其扩展为100像素,或者完全忽略它。
无论我做什么,我似乎都无法突破ClipRectangle。到目前为止,我已经尝试过:
e.ClipRectangle.Inflate(100, 0);
e.Graphics.ResetClip();
e.Graphics.SetClip(new Rectangle(x, y, w, h));
父控件正在调用Invalidate(true)(强制所有子控件的子控件失效)。
我也做了一些谷歌搜索并查看鲍勃鲍威尔的网站,但找不到核武器。
ResetClip将Graphics对象的剪切区域重置为无限大的Rectangle,但Graphics对象乐观地继续使用提供的ClipRectangle。
帮助。
答案 0 :(得分:5)
回顾:听起来你有一个带有自定义绘画方法的子控件。您希望在大于控件边界的区域中绘制控件。例如,如果将控件置于(10,10,100,100),则需要在(0,10,110,100)处绘制区域。
你不能完全这样做,传递给paint方法的控件的HDC是针对该控件的本机窗口句柄。它被操作系统和AFAIK截断,没有办法用HDC给绘制方法绘制它。
您可以做什么:一个选项是覆盖父窗口的create方法并删除窗口样式WS_CLIPCHILDREN(0x02000000),然后在父级的paint方法中绘制子项。
另一种选择是扩展子窗口的区域,使其包含您想要绘制的区域。如果还覆盖控件的OnPaintBackground方法,则可以防止背景绘制清除父级的渲染。这是有问题的,因为父级将剪切子区域而不刷新它。因此,您仍然需要删除父级的WS_CLIPCHILDREN才能使其正常工作。
我确信还有其他可能性基本上都是相同的结果,你不能这样做。
答案 1 :(得分:5)
Rectangle是一个结构,而不是一个类 - 它作为值传递,因此调用e.ClipRectangle.Inflate(100, 0);
在理论上无法帮助。
接下来您需要知道的是e.Graphics
与硬件设备上下文有关,因此Windows不会让您扩展绘图区域。解决方案是获取父窗口的设备上下文,然后在任何地方绘制。这是怎么做的:
[DllImport("User32.dll")]
static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("User32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
IntPtr dcPtr = GetDC(this.ParentForm.Handle);
Graphics g = Graphics.FromHdc(dcPtr);
// your code here
// don't forget to release it
g.Dispose();
ReleaseDC(this.ParentForm.Handle, dcPtr);