向表单添加控件的速度缓慢

发布于 2024-11-28 21:56:29 字数 1925 浏览 1 评论 0原文

为什么油漆要花这么长时间?

public Form1()
    {
        InitializeComponent();
        SuspendLayout();
        double scale = ClientSize.Width / 11;
        for (int i = 1; i < 10; i++)
        {
            for (int j = 1; j < 10; j++)
            {
                everybox[i - 1, j - 1] = new TextBox
                                             {
                                                 Location = new Point((int)(scale * i), (int)(scale * j)),
                                                 Size = new Size((int)scale - 2, (int)scale - 2),
                                                 Multiline = true
                                             };
                Controls.Add(everybox[i - 1, j - 1]);
            }
        }
        ResumeLayout();
    }


private void Form1_Paint(object sender, PaintEventArgs e)
    {
        float scale = ClientSize.Width / 11;
        Graphics g = this.CreateGraphics();
        int counter = 0;
        for (float i = scale; i <= this.ClientSize.Width - scale; i += scale)
        {
            counter++;
            if ((counter - 1) % 3 != 0)
            {
                g.DrawLine(new Pen(Color.Black), new Point((int)i, (int)scale),
                           new Point((int)i, ClientSize.Width - (int)scale));
                g.DrawLine(new Pen(Color.Black), new Point((int)scale, (int)i),
                           new Point(ClientSize.Width - (int)scale, (int)i));
            }
            else
            {
                g.DrawLine(new Pen(Color.Black, 3f), new Point((int)i, (int)scale),
                           new Point((int)i, ClientSize.Width - (int)scale));
                g.DrawLine(new Pen(Color.Black, 3f), new Point((int)scale, (int)i),
                           new Point(ClientSize.Width - (int)scale, (int)i));
            }
        }
    }

这是相当烦人的,并且会导致明显的滞后。 everybox 是一个 TextBox[9,9] 对象。

Why does the paint even take so long?

public Form1()
    {
        InitializeComponent();
        SuspendLayout();
        double scale = ClientSize.Width / 11;
        for (int i = 1; i < 10; i++)
        {
            for (int j = 1; j < 10; j++)
            {
                everybox[i - 1, j - 1] = new TextBox
                                             {
                                                 Location = new Point((int)(scale * i), (int)(scale * j)),
                                                 Size = new Size((int)scale - 2, (int)scale - 2),
                                                 Multiline = true
                                             };
                Controls.Add(everybox[i - 1, j - 1]);
            }
        }
        ResumeLayout();
    }


private void Form1_Paint(object sender, PaintEventArgs e)
    {
        float scale = ClientSize.Width / 11;
        Graphics g = this.CreateGraphics();
        int counter = 0;
        for (float i = scale; i <= this.ClientSize.Width - scale; i += scale)
        {
            counter++;
            if ((counter - 1) % 3 != 0)
            {
                g.DrawLine(new Pen(Color.Black), new Point((int)i, (int)scale),
                           new Point((int)i, ClientSize.Width - (int)scale));
                g.DrawLine(new Pen(Color.Black), new Point((int)scale, (int)i),
                           new Point(ClientSize.Width - (int)scale, (int)i));
            }
            else
            {
                g.DrawLine(new Pen(Color.Black, 3f), new Point((int)i, (int)scale),
                           new Point((int)i, ClientSize.Width - (int)scale));
                g.DrawLine(new Pen(Color.Black, 3f), new Point((int)scale, (int)i),
                           new Point(ClientSize.Width - (int)scale, (int)i));
            }
        }
    }

It is rather annoying, and causes noticeable lag. everybox is a TextBox[9,9] object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

把昨日还给我 2024-12-05 21:56:29

根据我的评论,更改

Graphics g = this.CreateGraphics();

为:

e.Graphics

Per my comment, change:

Graphics g = this.CreateGraphics();

to

e.Graphics
紫﹏色ふ单纯 2024-12-05 21:56:29

Paint 肯定会被多次调用,如果您收到太多调用,则可能与这段代码无关。有助于提高该特定位的性能的一件事是尝试减少您所做的工作量...

    Graphics g = e.Graphics;
    Pen bp = new Pen(Color.Black, 3f);
    Point start = new Point(0,0);
    Point stop = new Point(0,0);

    for (float i = scale; i <= this.ClientSize.Width - scale; i += scale)
    {
        int iAsInt = (int)i;
        int scaleAsInt = (int)scale;
        int w = ClientSize.Width;
        counter++;

        if ((counter - 1) % 3 != 0)
        {
            start.X = iAsInt;
            start.Y = scaleAsInt;
            stop.X = iAsInt;
            stop.Y = w-scaleAsInt;
            g.DrawLine(Pens.Black, start, stop);
            start.X = scaleAsInt;
            start.Y = iAsInt;
            stop.X = w-scaleAsInt;
            stop.Y = iAsInt;
            g.DrawLine(Pens.Black, start, stop);
            // Note: this looks like more work, but it is actually less
            // your code still has to make all the assignments in addition to 
            // newing up the points (and later having to garbage collect them)
        }
        else
        {
            // TODO: reuse the start/stop points here
            g.DrawLine(bp, new Point(iAsInt, scaleAsInt), new Point(iAsInt, w - scaleAsInt);
            g.DrawLine(bp, new Point(scaleAsInt, iAsInt), new Point(w - scaleAsInt, iAsInt));
        }
    }

要专门停止线条的过度绘制,请查看 PaintEventArgs 的 ClipRectangle 成员。如果线条的一部分落在剪辑矩形的区域内,请重新绘制它。

Paint can definitely get called alot and if you are getting too many calls, it probably has nothing to do with this bit of code. One thing that would help the performance of this particular bit is to try reducing the amount of work you do...

    Graphics g = e.Graphics;
    Pen bp = new Pen(Color.Black, 3f);
    Point start = new Point(0,0);
    Point stop = new Point(0,0);

    for (float i = scale; i <= this.ClientSize.Width - scale; i += scale)
    {
        int iAsInt = (int)i;
        int scaleAsInt = (int)scale;
        int w = ClientSize.Width;
        counter++;

        if ((counter - 1) % 3 != 0)
        {
            start.X = iAsInt;
            start.Y = scaleAsInt;
            stop.X = iAsInt;
            stop.Y = w-scaleAsInt;
            g.DrawLine(Pens.Black, start, stop);
            start.X = scaleAsInt;
            start.Y = iAsInt;
            stop.X = w-scaleAsInt;
            stop.Y = iAsInt;
            g.DrawLine(Pens.Black, start, stop);
            // Note: this looks like more work, but it is actually less
            // your code still has to make all the assignments in addition to 
            // newing up the points (and later having to garbage collect them)
        }
        else
        {
            // TODO: reuse the start/stop points here
            g.DrawLine(bp, new Point(iAsInt, scaleAsInt), new Point(iAsInt, w - scaleAsInt);
            g.DrawLine(bp, new Point(scaleAsInt, iAsInt), new Point(w - scaleAsInt, iAsInt));
        }
    }

To specifically stop the overdrawing of your lines, look at the ClipRectangle member of PaintEventArgs. If part of your line falls within the area of the clip rectangle, redraw it.

时光病人 2024-12-05 21:56:29

一个可能的原因是您试图绘制太多重量级组件。如果我的数学正确,您将重绘 9 * 9 * 9 * 9 = 6561 个对象。 WinForms 的设计并不支持以有效的方式重绘那么多组件。

您可能需要考虑是否真的需要在 WinForms 中使用那么多重量级图形组件。可能有更轻的组件,或者您可以根据上下文切换到 XNA(它具有相机、视图等 - 所有这些都减少了需要重绘的对象数量)或 WPF。

A possible reason is because you are trying to draw too many heavy-weight components. If my math is correct you are redrawing 9 * 9 * 9 * 9 = 6561 objects. WinForms are not designed to support redrawing of that many components in the efficient way.

You may need to think if you really need to use that many heavy-weight graphic components with WinForms. There might be lighter components or you can switch to XNA (which has camera, views etc - all of that reduce the number of objects needed to be redrawn) or WPF depending on the context.

把昨日还给我 2024-12-05 21:56:29

您发布的代码导致绘制事件触发 81 次 (9*9)。对于添加到表单的每个控件一次。任何更多的时间都是由于某些使表单无效的原因,例如鼠标在其上移动、另一个窗口在其上移动或表单大小调整。您未向我们展示的某些代码可能是有原因的。

The code you posted causes the paint event to fire 81 times (9*9). Once for each control being added to the form. Any more times are due to something that invalidates the form, like the mouse moving over it, another window moving over it, or the form resizing. Some code you aren't showing us may be responsible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文