C# 为什么画画慢?

C# 为什么画画慢?,c#,drawing,gdi+,C#,Drawing,Gdi+,我画一个线性梯度手动通过改变颜色画线。然而,这是非常缓慢的,我似乎更新,当我调整窗口的大小。我如何使它更快?在本例中,颜色比例是线性的,但后来我不想制作非线性渐变 protected override void OnPaintBackground(PaintEventArgs paintEvnt) { SuspendLayout(); // Get the graphics object Graphics

我画一个线性梯度手动通过改变颜色画线。然而,这是非常缓慢的,我似乎更新,当我调整窗口的大小。我如何使它更快?在本例中,颜色比例是线性的,但后来我不想制作非线性渐变

protected override void OnPaintBackground(PaintEventArgs paintEvnt)
        {
            SuspendLayout();

            // Get the graphics object
            Graphics gfx = paintEvnt.Graphics;
            // Create a new pen that we shall use for drawing the line

            // Loop and create a horizontal line 10 pixels below the last one
            for (int i = 0; i <= 500; i++)
            {
                Pen myPen = new Pen(Color.FromArgb(i/2,0,0));
                gfx.DrawLine(myPen, 0, i, 132, i);
            }

            ResumeLayout();

        }
受保护的覆盖无效OnPaintBackground(PaintEventArgs paintEvnt)
{
SuspendLayout();
//获取图形对象
Graphics gfx=paintEvnt.Graphics;
//创建一支新的笔,我们将使用它来画线
//循环并在最后一条下方10像素处创建一条水平线

对于(inti=0;i您可以预先计算颜色值,这样您就不必在每次重画时都这样做。除此之外,如果不使用更低级的API(如XNA),您就没有什么可以做的了


更新:在WinForms控件中托管XNA是完全可行的。在中有一些很好的正向链接。

如果您想在不调整大小的情况下只绘制一次,我建议您将其写入位图对象一次,然后将此位图绘制到背景。此外,您还可以在窗体上启用双缓冲。这应该是一个名为DoubleBuffering的属性,或者类似的属性。这样可以减少重新绘制表单时出现的闪烁。

问题是GDI+速度非常慢。

您应该使用GDI+的高级构造,它相对较快(相对于您现在所做的绘制线条而言)。有关
LinearGradientBrush
等的更多信息,请参阅。这些画笔和画笔有更多,可以帮助您提高性能

还有一件事:
Suspend/resumealayout
在您的示例中没有任何作用。这些方法仅适用于您通过向当前表单添加
控件
s或更改现有
控件
的属性(如
停靠
属性或
高度
宽度
来进行布局的情况

也许指定一个与Pieter建议的
LinearGradientBrush
一起使用可以解决您将来绘制非线性渐变的问题

您可以创建一个
ColorBlend
对象,该对象指定您选择的颜色以及每个颜色的任意位置。通过将
LinearGradientBrush
InterpolationColors
属性设置到
ColorBlend
对象,您应该能够获得想要的任何效果

MSDN提供了以下示例:

protected override void OnPaint(PaintEventArgs e)
{
    //Draw ellipse using ColorBlend.
    Point startPoint2 = new Point(20, 110);
    Point endPoint2 = new Point(140, 110);
    Color[] myColors = {Color.Green, Color.Yellow, Color.Yellow, Color.Blue, Color.Red, Color.Red};
    float[] myPositions = {0.0f,.20f,.40f,.60f,.80f,1.0f};
    ColorBlend myBlend = new ColorBlend();
    myBlend.Colors = myColors;
    myBlend.Positions = myPositions;
    LinearGradientBrush lgBrush2 = new LinearGradientBrush(startPoint2, endPoint2, Color.Green, Color.Red);
    lgBrush2.InterpolationColors = myBlend;
    Rectangle ellipseRect2 = new Rectangle(20, 110, 120, 80);
    e.Graphics.FillEllipse(lgBrush2, ellipseRect2);
}

是的,将笔数组存储在方法之外,只创建一次,应该可以提高效率。@Pieter-我曾尝试使用liniargradienbrush,但我不允许我做非线性渐变,这正是我试图实现的。我理解。然而,你所采取的方法,无论它多么容易理解(在那里,做到了:)),非常慢。这是GDI+。如果这是用于自定义控件,可以尝试设置
this.SetStyle(ControlStyles.DoubleBuffer,true)在构造函数中,这有帮助。@ PiTeer-OK,这导致了一个改进,但是现在它仍然太慢。XNA是GDI+的唯一替代物吗?@ BieldSo-我将非常认真地考虑WPF。我已经做了切换,并且没有回头看。WPF是DirectX的,所以这些问题根本不适用。@ PiTeTe:我可以,我可以。看到了改用WPF的好处,但现在我正在为一个不支持WPF的平台开发插件。现在这也是一个很好的解决方案——但正如我写给Pieter的信中所说,希望我能很快过渡到WPF。