Question

I am working on a project using .Net Compact Framework 3.5 using C# 3.0.

I have a user control which receives data every 15 miliseconds and I have to draw shapes

like lines, rectangle, filled rectangles on user control.

I want to know what is the fastest way to draw these shapes, I am also open to use P/Invoke methods if there are some to increase performance and speed.

The code I am using is as follows:

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

I am using drawing order and shape like step line , line , framed rectangle ( just rectangle ) and rectangle is filled rectangle.

Because of performance critical application I want to know the fastest way of drawing these shapes.

Thanks in advance for any suggestion.

Was it helpful?

Solution

Are you familiar with double-buffering? Keep an offscreen image buffer to do your writes to as the changes come in. Then override the OnPaint to blit the whole image in one statement. Also, override the OnPaintBackground with a no-op to get rid of the default behavior of clearing the control to its backcolor on each paint.


Old as the hills, but here is an article on some best-practices on using GDI in the Compact Framework.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top