1

I have a Windows Forms app where I add different figures(rectangles, circles, etc.) to the main form. The figure is a UserControl and it's shape I define with GraphicsPath. Method for adding new figure:

 void AddElement(ShapeType shape, string guid)
    {
        Shape newShape = new Shape();
        newShape.Name = guid;
        newShape.Size = new Size(100, 100);           
        newShape.Type = shape;
        newShape.Location = new Point(100, 100);

        newShape.MouseDown += new MouseEventHandler(Shape_MouseDown);
        newShape.MouseMove += new MouseEventHandler(Shape_MouseMove);
        newShape.MouseUp += new MouseEventHandler(Shape_MouseUp);
        newShape.BackColor = this.BackColor;

        this.Controls.Add(newShape);
    }

In Shape (Figure) class:

 private ShapeType shape;
 private GraphicsPath path = null;
 public ShapeType Type
    {
        get { return shape; }
        set
        {
            shape = value;
            DrawElement();
        }
    } 

 private void DrawElement()
     {
        path = new GraphicsPath();
        switch (shape)
        {
            case ShapeType.Rectangle:
                path.AddRectangle(this.ClientRectangle);
                break;

            case ShapeType.Circle:
                path.AddEllipse(this.ClientRectangle);
                break;

            case ShapeType.Line:
                path.AddLine(10,10,20,20);                   
                break;
        }
        this.Region = new Region(path);
    }

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        if (path != null)
        {              
            e.Graphics.DrawPath(new Pen(Color.Black, 4), path);
        }
    }

When resizing the figure, I redraw It:

 protected override void OnResize(System.EventArgs e)
    {
        DrawElement();
        this.Invalidate();
    }

Everything works fine when I add shapes like rectangle and circle. But when I choose Line, nothing appears on my form. The breakpoint shows that the programs steps in all the methods and this.Controls.Add(newShape); as well.

I do not understand why this is not working. I'd appreciate any advice.

Gyuzal
  • 1,581
  • 10
  • 52
  • 99
  • What's the purpose of this line: `this.Region = new Region(path);`? Can you try to remove it? – Ulugbek Umirov Mar 29 '14 at 20:20
  • It sets the region of the form associated with the control. Once I remove it, the form of my control will not be a circle or line anymore. – Gyuzal Mar 29 '14 at 20:32
  • Yes, but what do you expect when you set the region to a line? A graphicsPath doesn't need to be closed, but a straight line can't produce a useful region! – TaW Mar 29 '14 at 20:45
  • I think there should be a workaround. – Gyuzal Mar 29 '14 at 20:55
  • possible duplicate of [Moving a drawn line with the mouse](http://stackoverflow.com/questions/8448302/moving-a-drawn-line-with-the-mouse) – Dour High Arch Mar 29 '14 at 22:10

2 Answers2

2

You can draw an open GraphicsPath with a thin or a thick Pen. But a region must be set from a closed shape or else there is no place where your pixels could show up. This will help to keep your region intact; but you need to know, just what you want it to be:

if (shape != ShapeType.Line)   this.Region = new Region(path);

If you want it to be something like a thick line you must create a polygon or a series of lines to outline the shape you want. And if you want your line to be inside that region you will need two paths: one closed polygon path to set the region and one open line path to draw the line inside the region.

Edit: The best way to create the closed path is probably to use the Widen() method with the Pen you are using like this:

GraphicsPath path2 = path.Widen(yourPen);

This would get the thickness right as well as the line caps and also work for more complicated polylines; I haven't tried it though..

TaW
  • 53,122
  • 8
  • 69
  • 111
  • Thank you, I use rectangle with the smallest Height possible and appropriate width of Pen to have a filled look :) – Gyuzal Mar 29 '14 at 22:45
  • 1
    If you're happy, then I'm happy; sorry about the gender error on my side. The rectangle you describe is ok for horizontal lines but if you want lines that go in all angles maybe you can use the improved method in my answer. – TaW Mar 29 '14 at 23:22
1

Maybe it's because the line has no area. Try to replace it with a very thin shape having a positive area. For instance:

const int thickness = 1;
path.AddLines(new[]
    {
        new Point(10, 10),
        new Point(20, 20),
        new Point(20 + thickness, 20 + thickness),
        new Point(10 + thickness, 10 + thickness)
    });
Dmitry
  • 13,797
  • 6
  • 32
  • 48
  • "line has no area". Thank you, now I get the reason. I tried your suggestion but it still does not work. Is there any other way? – Gyuzal Mar 29 '14 at 20:36
  • If it doesn't work, then my guess was wrong. Just in case I've updated the answer, please revise it. – Dmitry Mar 29 '14 at 20:42
  • A graphicsPath doesn't need to be closed. But as he sets the region to the line, it is useless. – TaW Mar 29 '14 at 20:46
  • @TaW, thank you. I removed the useless line. And *she*, not *he*. :) – Dmitry Mar 29 '14 at 20:50
  • I've revised my answer for the [similar problem](http://stackoverflow.com/questions/22467480/how-to-create-a-form-in-shape-of-rhomb/22467541#22467541) and came to conclusion, that it should work. Please try to increase a thickness. I've got no more ideas, sorry. – Dmitry Mar 29 '14 at 21:22
  • Anyways, thanks for your effort @Dmitry. I found a good solution here: http://stackoverflow.com/questions/8448302/moving-a-drawn-line-with-the-mouse – Gyuzal Mar 29 '14 at 21:30