C# “面板绘制”中的图形渲染不完整的对象

C# “面板绘制”中的图形渲染不完整的对象,c#,winforms,C#,Winforms,每天好,我有这个代码来创建一个简单的圆圈 private void panel1_Paint(object sender, PaintEventArgs e) { Graphics g; Pen myPen = new Pen(Color.Black, 1); Point sp = new Point(5, 5);//starting point sp Point ep = new

每天好,我有这个代码来创建一个简单的圆圈

 private void panel1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g;
            Pen myPen = new Pen(Color.Black, 1);
            Point sp = new Point(5, 5);//starting point sp
            Point ep = new Point(100, 100);//ending point ep
            g = this.CreateGraphics();//tells compiler that we are going to draw on this very form
            g.DrawLine(myPen, sp, ep);

            g = this.CreateGraphics();
            g.DrawEllipse(myPen, 0, 0, 90, 90);

        }
问题是,当我运行它时,我会呈现这种不完整的输出

你能告诉我为什么会这样吗?多谢各位

g = this.CreateGraphics();//tells compiler that we are going to draw on this very form
您是在窗体上而不是在面板中绘制它。在“隐藏面板”的“面板”中绘制它

g = this.pnlName.CreateGraphics();
要绘制内部面板,请参见Hans Passant的答案。既然这是公认的答案,我也在这里添加代码

 e.Graphics.DrawEllipse(myPen, 0, 0, 90, 90);

您可以删除面板并使用代码,也可以在面板上绘制代码

private void panel1_Paint(object sender, PaintEventArgs e)
    {
        Graphics g;
        Pen myPen = new Pen(Color.Black, 1);
        Point sp = new Point(5, 5);//starting point sp
        Point ep = new Point(100, 100);//ending point ep
        //Paint it on panel
        g = panel1.CreateGraphics();//tells compiler that we are going to draw on this very form
        g.DrawLine(myPen, sp, ep);

        //Paint it on panel
        g = panel1.CreateGraphics();
        g.DrawEllipse(myPen, 0, 0, 90, 90);
    }
永远不要使用CreateGraphics,它只适用于游戏风格的基于框架的绘图。当你创建一个每一帧都不一样的游戏时,你所做的那种。通过使用此选项,将创建渲染到窗体曲面而不是面板的图形对象,从而使问题更加复杂。它由窗体上的控件剪裁,即您案例中的面板

Paint事件已经为您提供了一个准备绘制到控制曲面的图形对象。或者将DoubleBuffered属性设置为true得到的双缓冲区,这是下一个可能的问题。还应处理所使用的图形对象。修正:

    private void panel1_Paint(object sender, PaintEventArgs e) {
        using (var myPen = new Pen(Color.Black, 1)) {
            e.Graphics.DrawLine(myPen, new Point(5, 5), new Point(100, 100));
            e.Graphics.DrawEllipse(myPen, 0, 0, 90, 90);
        }
    }

抑制Panel类使用的优化也很重要。作为一个容器控件,它将在调整大小时重新绘制的内容限制为仅显示控件的一部分。当您绘制的内容也取决于面板的大小时,可能会产生令人不快的涂抹效果。通过在构造函数中将其ResizeRedraw属性设置为true来抑制此优化,从面板中导出您自己的类是必要的。

您确定面板前面没有任何东西会影响剪裁吗?哦,哦,哦,哦,哦,哦,哦,我明白了,所以绘图是在表格上而不是在面板上绘制的。我如何在面板内绘制圆?不,他不是这么说的;您需要确保您正在绘制的面板上没有其他控件,例如面板。@Medinoc我已经看到了如何操作。谢谢您的帮助,面板上方有一个面板,使其在后面呈现。请将其作为答案发布,我会接受它。谢谢:不要创建您自己的图形,用e.图形代替。这不是正确答案。它似乎可以工作,但当面板被双缓冲时,它会失败得很惨。始终使用Paint事件的e.Graphics对象。
    private void panel1_Paint(object sender, PaintEventArgs e) {
        using (var myPen = new Pen(Color.Black, 1)) {
            e.Graphics.DrawLine(myPen, new Point(5, 5), new Point(100, 100));
            e.Graphics.DrawEllipse(myPen, 0, 0, 90, 90);
        }
    }