绘制形状的最快方法(Line,FilledRectangle,Rectangle等)

时间:2012-07-16 10:30:31

标签: c# compact-framework .net-cf-3.5

我正在使用C#3.0使用.Net Compact Framework 3.5开发一个项目。

我有一个用户控件,每15毫秒接收一次数据,我必须绘制形状

像用户控件上的线条,矩形,填充矩形。

我想知道绘制这些形状的最快方法是什么,如果有一些方法可以提高性能和速度,我也可以使用P / Invoke方法。

我使用的代码如下:

     private void DrawThreeFunctions(Graphics g)
                {
                    // drawing back functions
                    if (DisplayFunction1.DrawOrder == DrawOrder.Back && GraphDataArray.Length > 0)
                    {
                        DrawFunction(g, DisplayFunction1, GraphDataArray[0]);
                    }
                    if (DisplayFunction2.DrawOrder == DrawOrder.Back && GraphDataArray.Length > 1)
                    {
                        DrawFunction(g, DisplayFunction2, GraphDataArray[1]);
                    }
                    if (DisplayFunction3.DrawOrder == DrawOrder.Back && GraphDataArray.Length > 2)
                    {
                        DrawFunction(g, DisplayFunction3, GraphDataArray[2]);
                    }
                    // drawing middle functions
                    if (DisplayFunction1.DrawOrder == DrawOrder.Middle && GraphDataArray.Length > 0)
                    {
                        DrawFunction(g, DisplayFunction1, GraphDataArray[0]);
                    }
                    if (DisplayFunction2.DrawOrder == DrawOrder.Middle && GraphDataArray.Length > 1)
                    {
                        DrawFunction(g, DisplayFunction2, GraphDataArray[1]);
                    }
                    if (DisplayFunction3.DrawOrder == DrawOrder.Middle && GraphDataArray.Length > 2)
                    {
                        DrawFunction(g, DisplayFunction3, GraphDataArray[2]);
                    }
                    // drawing front functions
                    if (DisplayFunction1.DrawOrder == DrawOrder.Front && GraphDataArray.Length > 0)
                    {
                        DrawFunction(g, DisplayFunction1, GraphDataArray[0]);
                    }
                    if (DisplayFunction2.DrawOrder == DrawOrder.Front && GraphDataArray.Length > 1)
                    {
                        DrawFunction(g, DisplayFunction2, GraphDataArray[1]);
                    }
                    if (DisplayFunction3.DrawOrder == DrawOrder.Front && GraphDataArray.Length > 2)
                    {
                        DrawFunction(g, DisplayFunction3, GraphDataArray[2]);
                    }
                } 


    private void DrawFunction(Graphics g, DisplayFunction function, int[] data)
            {
                Color color = Utils.GetColor(function.Color);
                switch (function.Shape)
                {
                    case FunctionShape.StepLine:
                        DrawStepLines(g, data, color);
                        break;
                    case FunctionShape.Rectangle:
                        DrawFilledRectangles(g, data, color);
                        break;
                    case FunctionShape.FramedRectangle:
                        DrawFramedRectangles(g, data, color);
                        break;
                    case FunctionShape.Line:
                        DrawLines(g, data, color);
                        break;
                    default:
                        break;
                }
            }

            #region Drawing methods
            // drawing lines
            private void DrawLines(Graphics g, int[] lineData, Color lineColor)
            {
                BarPositions = new List<int>();
                List<Point> linePoints = new List<Point>();
                int lineYPos = -1;
                int lineXPos = FirstBarDrawPosition;
                Point point = Point.Empty;

                using (Pen linePen = new Pen(lineColor, 2.0f))
                {
                    for (int i = FirstVisibleItemIndex, k = 0; i < _indexLimit; i++, k++)
                    {
                        if (base.GetBarEndPosition(k) > Width)
                            break;

                        lineXPos = GetTickPosition(k);
                        BarPositions.Add(lineXPos);

                        if (i < lineData.Length)
                            lineYPos = lineData[i];
                        else
                            continue;

                        point.X = lineXPos;
                        point.Y = lineYPos;

                        linePoints.Add(point);
                    }

                    if (linePoints.Any())
                    {
                        g.DrawLines(linePen, linePoints.ToArray());
                    }
                }
            }
            // drawing framed rectangles
            private void DrawFramedRectangles(Graphics g, int[] functionValues, Color functionColor)
            {
                BarPositions = new List<int>();

                int barXPos = FirstBarDrawPosition;
                Rectangle barRect = Rectangle.Empty;
                barRect.Width = WidthOfBar - 1;
                int barYPos = -1;

                using (Pen barPen = new Pen(functionColor))
                {
                    for (int i = FirstVisibleItemIndex, k = 0; i < _indexLimit; i++, k++)
                    {
                        if (base.GetBarEndPosition(k) > Width)
                            return;

                        BarPositions.Add(GetTickPosition(k));

                        if (i < functionValues.Length)
                            barYPos = functionValues[i];
                        else
                            continue;

                        //barRect = new Rectangle();
                        barRect.X = barXPos;
                        barRect.Y = barYPos;
                        //barRect.Width = WidthOfBar - 1;
                        barRect.Height = Height - barYPos;
                        g.DrawRectangle(barPen, barRect);
                        barXPos += (WidthOfBar + DistanceBetweenBars);
                    }
                }
            }
            // drawing filled rectangles
            private void DrawFilledRectangles(Graphics g, int[] functionValues, Color functionColor)
            {
                BarPositions = new List<int>();

                int barXPos = FirstBarDrawPosition;
                Rectangle barRect = Rectangle.Empty;
                barRect.Width = WidthOfBar;
                int barYPos = -1;

                using (SolidBrush barBrush = new SolidBrush(functionColor))
                {
                    for (int i = FirstVisibleItemIndex, k = 0; i < _indexLimit; i++, k++)
                    {
                        if (base.GetBarEndPosition(k) > Width)
                            return;

                        BarPositions.Add(GetTickPosition(k));

                        if (i < functionValues.Length)
                            barYPos = functionValues[i];
                        else
                            continue;

                        //barRect = new Rectangle();
                        barRect.X = barXPos;
                        barRect.Y = barYPos;
                        //barRect.Width = WidthOfBar;
                        barRect.Height = Height - barYPos;
                        g.FillRectangle(barBrush, barRect);
                        barXPos += (WidthOfBar + DistanceBetweenBars);
                    }
                }
            }

private void DrawStepLines(Graphics g, int[] lineData, Color lineColor)
        {
            BarPositions = new List<int>();
            int lineYPos = -1;
            int barXPos = FirstBarDrawPosition;

            using (Pen linePen = new Pen(lineColor, 2.0f))
            {
                for (int i = FirstVisibleItemIndex, k = 0; i < _indexLimit; i++, k++)
                {
                    if (base.GetBarEndPosition(k) > Width)
                        return;

                    BarPositions.Add(GetTickPosition(k));

                    if (i < lineData.Length)
                        lineYPos = lineData[i];
                    else
                        continue;

                    // draw third function line
                    //lineHeight = lineData[i];

                    g.DrawLine(linePen, barXPos, lineYPos, barXPos + WidthOfBar - 1, lineYPos);

                    barXPos += (WidthOfBar + DistanceBetweenBars);
                }
            }
        }

我正在使用绘制顺序和形状,如步线,直线,框架矩形(只是矩形)和矩形填充矩形。

由于性能关键应用,我想知道绘制这些形状的最快方法。

提前感谢任何建议。

1 个答案:

答案 0 :(得分:3)

你熟悉双缓冲吗?保持屏幕外图像缓冲区以便在更改进入时进行写入。然后重写OnPaint以在一个语句中对整个图像进行blit。此外,使用no-op覆盖OnPaintBackground以消除在每个绘制上将控件清除为其背景颜色的默认行为。


旧的山丘,但here是关于在Compact Framework中使用GDI的一些最佳实践的文章。