SunYi
SunYi

Reputation: 11

Graphics.DrawLine() Always Throw the OutofMemoryException in Some Condition

Here are my codes. A very simple method that handles the System.Windows.Forms.Form.Paint event.

void Form1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
    PointF start = new PointF(121.0F, 106.329636F);
    PointF end = new PointF(0.9999999F, 106.329613F);

    using (Pen p05 = new Pen(Color.Red, 1F))
    {
        p05.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
        p05.DashPattern = new float[] { 4, 2, 1, 3 };
        e.Graphics.DrawLine(p05, start, end);
    }
}

This method always throws the OutofMemoryException.

I have tested the code under WindowsXP32bit .Net Framework 2.0,3.0 and 3.5,and the result are the same.But it works fine under Windows732bit and Net Framework 2.0,3.0 and 3.5.

Here are what i do to stop the code from throwing the OutofMemoryException.(1 or 2 or 3)

1.Set the Graphics.SmoothingMode to System.Drawing.Drawing2D.SmoothingMode.Default

2.Change the end point to PointF(0.99999F, 106.329613F)

3.Set the DashStyle to System.Drawing.Drawing2D.DashStyle.Solid

But i do need the SmoothingMode and DashStyle. And in the real program the coordinate of the point to draw are always transformed by a Matrix which represents the movement ,rotation ,and scaling that applied to the underlaying image.So coordinate like (0.9999999F, 106.329613F) are possible.

Could you please tell me how to handle this annoying problem.

Best Regards,

STACK TRACE

FULL SOURCE

Form1.designer.cs

namespace WindowsFormsApplication1
    {
        partial class Form1
        {
            private System.ComponentModel.IContainer components = null;

            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }

            private void InitializeComponent()
            {
                this.SuspendLayout();
                //
                // Form1
                //
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(292, 266);
                this.Name = "Form1";
                this.Text = "Form1";
                this.ResumeLayout(false);
            }
        }
    }

Form1.cs

using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            p05 = new Pen(Color.Red, 1F);
            p05.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
            p05.DashPattern = dashStyle;
            this.Paint += new PaintEventHandler(Form1_Paint);
        }

        void Form1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            e.Graphics.DrawLine(p05, start, end);
        }

        // start and end point are within the
        // client rectangle of the form which has been specified in the designer (292, 266);
        private PointF start = new PointF(121.0F, 106.329636F);
        private PointF end = new PointF(0.9999999F, 106.329613F);
        private float[] dashStyle = new float[] { 4, 2, 1, 3 };
        private Pen p05;
    }
}

Upvotes: 1

Views: 3373

Answers (1)

vulkanino
vulkanino

Reputation: 9134

It could really be an Out Of Memory error; since some of your data is constant, please try to put that data outside the Paint method, so you don't have to call New:

void Form1_Paint(object sender, PaintEventArgs e)
        {
            //e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            using ( redPen )
            {
                redPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
                redPen.DashPattern = dashPattern;
                e.Graphics.DrawLine(redPen, startingPoint, endingPoint);
            }
        }

private PointF startingPoint = new PointF(121.0F, 106.329636F);
private PointF endingPoint = new PointF(0.9999999F, 106.329613F);
private Pen redPen = new Pen(Color.Red, 1F);
private float[] dashPattern = { 4, 2, 1, 3 };

Another thing to consider is the graphics bounds. Before doing anything else, do:

  e.DrawBackground();
  Rectangle r = e.Bounds;

And then draw into the rectangle bounds.

edit: add the paint handler in the Load event, not in the constructor.

Upvotes: 0

Related Questions