none
The line is not visisble when drawline() is used before FillRectangle() method RRS feed

  • Question

  • Hi

    I tried to draw a line inside a rectangle and filled the rectangle with a colour using the below code in Onpaint method. The line is invisible.But if i draw line after filling the rectangle it works good. Should i set any property to make the line visible

    protected override void OnPaint(PaintEventArgs args)
    {
    Graphics g = args.Graphics;
    g.DrawLine(new Pen(Color.Black, 3), 50, 60, 70, 80);   //This line is not visible
    g.DrawRectangle(
    new Pen(Color.Blue, 3),
    new Rectangle(10, 10, 500, 500));
    g.FillRectangle(Brushes.Red,
    new Rectangle(10, 10, 500, 500));
    g.DrawLine(new Pen(Color.DarkGreen, 3), 20, 30, 40, 40); //This line is visible.

    If i didnt fill the rectangle both the lines are visible. Can anyone help me on this

    Thanks,

    Prahal

    Monday, September 17, 2012 8:12 AM

Answers

  • Hi, the blue line will be visible:

        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                this.Paint += new PaintEventHandler(Form1_Paint);
            }
    
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                using (Pen p = new Pen(Color.Blue, 4))
                {
                    //draw the first line
                    e.Graphics.DrawLine(p, 0, 0, 200, 200);
    
                    using (System.Drawing.Drawing2D.GraphicsPath gP = new System.Drawing.Drawing2D.GraphicsPath())
                    {
                        //add the same line to the gP and widen with the pen the line is drawn with
                        gP.AddLine(0, 0, 200, 200);
                        gP.Widen(p);
    
                        using (System.Drawing.Drawing2D.GraphicsPath gP2 = new System.Drawing.Drawing2D.GraphicsPath())
                        {
                            //add the rectangle to the second GP
                            gP2.AddRectangle(new Rectangle(0, 0, 200, 200));
    
                            //create Regions, exclude the second from first
                            using (Region reg = new Region(gP2))
                            {
                                using (Region reg2 = new Region(gP))
                                {
                                    reg.Exclude(reg2);
    
                                    //and fill the region instead of the rectangle
                                    e.Graphics.FillRegion(Brushes.Red, reg);
                                }
                            }
                        }
                    }
                }
            }
        }

    Edit: Added some comments

    But also in this approach you have to somehow get the numerical data of your "other system" [so that you also could draw it after filling the rectangle]. If you only can get the already drawn content, you'll have to do some image-processing. Either vectorize the drawn shapes, or fill the space between the shapes.

    Regards,

      Thorsten


    Tuesday, September 18, 2012 12:34 PM

All replies

  • Hi, if you want to see both lines, draw them after filling the rectangle. GDI+ draws as coded. If you draw a line onto a paper, then fill the entire paper with a solid-color and again draw a line, also only the second line will be visible, the first one will be overdrawn.

    Regards,

      Thorsten

    Monday, September 17, 2012 8:19 AM
  • Thanks for the reply. so no other way is there to make both the lines visible other than filling the rectangle before drawing the lines?
    Monday, September 17, 2012 8:34 AM
  • In the code you posted, there doesn't appear to be a problem drawing both lines after the rectangle is filled.  If you must fill the rectangle after other drawing within the rectangle, try setting CompositionMode = CompositingMode.SourceOver before filling the rectangle.
    • Edited by JohnWein Monday, September 17, 2012 8:53 AM
    Monday, September 17, 2012 8:52 AM
  • Hi

    Thanks for the response. The code which i posted is generated from some other system so the line must be drawn before filling the rectangle.

    Could you please tell me where i can get the property  CompositionMode?

    or post a sample code

    Tuesday, September 18, 2012 7:09 AM
  • Boss, 

    i tried with

    g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver; before filling the rectangle but that doesn't help.


    • Edited by Prahalnathan Tuesday, September 18, 2012 12:01 PM
    Tuesday, September 18, 2012 7:21 AM
  • Hi

    Thanks for the response. The code which i posted is generated from some other system so the line must be drawn before filling the rectangle.

    Could you please tell me where i can get the property  CompositionMode?

    or post a sample code

    Hi, the CompositingMode will not help you here [when drawing in one pass]. You only can set the values "overdraw-current" and "replace-current (by source)", so in both cases your line will be invisible [when using an opaque brush].

    If you cannot draw the line after filling the rectangle, you could create a Region, exclude the parts the line covers and fill that Region rather than the Rectangle.

    Regards,

      Thorsten


    Tuesday, September 18, 2012 11:37 AM
  • Hi 

    can you post some sample code/link to create a region.

    Tuesday, September 18, 2012 12:20 PM
  • Hi, the blue line will be visible:

        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                this.Paint += new PaintEventHandler(Form1_Paint);
            }
    
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                using (Pen p = new Pen(Color.Blue, 4))
                {
                    //draw the first line
                    e.Graphics.DrawLine(p, 0, 0, 200, 200);
    
                    using (System.Drawing.Drawing2D.GraphicsPath gP = new System.Drawing.Drawing2D.GraphicsPath())
                    {
                        //add the same line to the gP and widen with the pen the line is drawn with
                        gP.AddLine(0, 0, 200, 200);
                        gP.Widen(p);
    
                        using (System.Drawing.Drawing2D.GraphicsPath gP2 = new System.Drawing.Drawing2D.GraphicsPath())
                        {
                            //add the rectangle to the second GP
                            gP2.AddRectangle(new Rectangle(0, 0, 200, 200));
    
                            //create Regions, exclude the second from first
                            using (Region reg = new Region(gP2))
                            {
                                using (Region reg2 = new Region(gP))
                                {
                                    reg.Exclude(reg2);
    
                                    //and fill the region instead of the rectangle
                                    e.Graphics.FillRegion(Brushes.Red, reg);
                                }
                            }
                        }
                    }
                }
            }
        }

    Edit: Added some comments

    But also in this approach you have to somehow get the numerical data of your "other system" [so that you also could draw it after filling the rectangle]. If you only can get the already drawn content, you'll have to do some image-processing. Either vectorize the drawn shapes, or fill the space between the shapes.

    Regards,

      Thorsten


    Tuesday, September 18, 2012 12:34 PM