[英]Graphics bug when dragged off-screen
I have wrote this code that will create a rounded corner border around a panel. 我已经编写了这段代码,它将在面板周围创建圆角边框。
public void DrawRoundRect(Graphics g, Pen p, float X, float Y, float width, float height, float radius)
{
GraphicsPath gp = new GraphicsPath();
//Upper-right arc:
gp.AddArc(X + width - (radius * 2), Y, radius * 2, radius * 2, 270, 90);
//Lower-right arc:
gp.AddArc(X + width - (radius * 2), Y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
//Lower-left arc:
gp.AddArc(X, Y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
//Upper-left arc:
gp.AddArc(X, Y, radius * 2, radius * 2, 180, 90);
gp.CloseFigure();
g.DrawPath(p, gp);
gp.Dispose();
}
private void panel_Paint(object sender, PaintEventArgs e)
{
Graphics v = e.Graphics;
DrawRoundRect(v, Pens.White, e.ClipRectangle.Left, e.ClipRectangle.Top, e.ClipRectangle.Width - 1, e.ClipRectangle.Height - 1, 10);
base.OnPaint(e);
}
It works fine, until it goes off screen and this happens: 它可以正常工作,直到离开屏幕并发生这种情况:
Does anyone know what I've done wrong, or how to fix the issue? 有谁知道我做错了什么,或者如何解决这个问题?
You misunderstand what ClipRectangle
means. 您误解了
ClipRectangle
含义。
It doesn't tell you how big the panel is - it tells you which part of the panel to redraw. 它不会告诉您面板有多大,而是会告诉您要重画面板的哪一部分。 As you move the form off-screen, it needs to redraw the parts that changed monitors - but not the ones that remain on the original one.
当您将表格移出屏幕时,它需要重新绘制更改了监视器的部件,而不是重新保留在原始监视器上的部件。 So instead of redrawing the whole panel (when
ClipRectangle
is the whole area of the panel, and your code works), it tells you to only redraw a part of it - and ClipRectangle
is much smaller than the panel you're trying to draw. 因此,它不会重绘整个面板(当
ClipRectangle
是面板的整个区域,并且您的代码有效时),它告诉您仅重绘一部分面板-并且ClipRectangle
比您要绘制的面板小得多。
ClipRectangle
is really an optimization feature. ClipRectangle
实际上是一种优化功能。 If you don't care about that, you can pretty much ignore it completely - just use 0, 0, panel.Width, panel.Height
. 如果您不在乎,则可以完全忽略它-只需使用
0, 0, panel.Width, panel.Height
。
You have two problems. 你有两个问题。 First is relying on e.ClipRectangle, that is not the size of the panel.
首先是依赖e.ClipRectangle,而不是面板的大小。 You need to use
panel.ClientRectangle
instead. 您需要改用
panel.ClientRectangle
。 That's what causes the smearing when you drag it off the screen and back. 这就是将拖尾从屏幕上拖回时导致拖尾的原因。
You haven't found the next one yet, it is much more subtle. 您还没有找到下一个,它更加微妙。 Panel was designed to be a container control and it optimizes its painting.
Panel被设计为容器控件,并且可以优化其绘画。 Redrawing only the parts that get revealed when it is resized.
重绘仅在调整大小时显示的部分。 Pretty important, makes resizing a window more bearable.
非常重要,这使得调整窗口大小更加可承受。 That however will not work well for details like this, the rounded corners will not get properly repainted.
但是,对于这样的细节来说效果不佳,圆角将无法正确地重新粉刷。 Looks like a smearing effect as well, less pronounced than what you have now.
看起来也像是拖影效果,不如现在那么明显。 It will happen whenever you resize the panel, typically with the Dock or Anchor property.
每当您调整面板的大小(通常使用Dock或Anchor属性)时,就会发生这种情况。
Proper way to do that is to derive your own class from Panel, set the ResizeRedraw property to true in the constructor. 正确的方法是从Panel派生您自己的类,在构造函数中将ResizeRedraw属性设置为true。 You typically almost always also want to set DoubleBuffered to true to suppress the visible flicker you now have.
通常,您通常几乎总是希望将DoubleBuffered设置为true,以抑制您现在可见的闪烁。 Or use the panel's Resize event, call panel.Invalidate().
或使用面板的Resize事件,调用panel.Invalidate()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.