在屏幕外拖动图形错误

时间:2015-10-22 12:37:09

标签: c# .net

我已编写此代码,将在面板周围创建圆角边框。

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);
}

它工作正常,直到它离开屏幕并发生这种情况: enter image description here

有谁知道我做错了什么,或者如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

你误解了ClipRectangle的含义。

它不会告诉您面板有多大 - 它会告诉您要重绘的面板的哪个部分。当您在屏幕外移动表单时,它需要重绘已更改监视器的部分 - 而不是原始部分上保留的部分。因此,不是重新绘制整个面板(当ClipRectangle是面板的整个区域,并且您的代码正常工作时),它会告诉您只重绘其中的一部分 - 并且ClipRectangle远小于你试图画的小组。

ClipRectangle实际上是一种优化功能。如果你不关心它,你几乎可以完全忽略它 - 只需使用0, 0, panel.Width, panel.Height

答案 1 :(得分:3)

你有两个问题。首先是依赖于e.ClipRectangle,即面板的大小。您需要使用panel.ClientRectangle代替。当你将它拖离屏幕并返回时,这就是导致拖尾的原因。

你还没有找到下一个,它更加微妙。 Panel被设计成一个容器控件,它优化了它的绘画。仅重新绘制调整大小时显示的部分。非常重要,使窗口的大小更加可以忍受。然而,对于这样的细节,这不会很好,圆角将无法正确重新绘制。看起来像涂抹效果,不如你现在的那么明显。每当您调整面板大小时,通常会使用Dock或Anchor属性。

这样做的正确方法是从Panel派生自己的类,在构造函数中将ResizeRedraw属性设置为true。您通常几乎总是希望将DoubleBuffered设置为true以抑制您现在可见的闪烁。或者使用面板的Resize事件,调用panel.Invalidate()。