Search code examples
c#.netwinformsc++-cli

How can I draw an arrow shape which can be moved and resized in c#


I'm new for window application development, currently I am working at a flow chart winform project. I need draw a control like the picture show(copy from MS word, by Insert->Shapes->Block Arrows). [Arrow shape] [1]: https://i.sstatic.net/P7XBL.png This arrow can be moved, resized and reshaped. I have looked for some solutions, but most of them are regular shapes. Could I create a list and put all the 7 points of the arrow to this list, then draw the line between the points, one line by one line(Graphics::DrawImage)? If yes, then the next question is, how can I fill this irregular shape with some solid color? And how can I move this shape? If I redraw it, how to erase the old shape?

Current I can drag and move a control using following code, but for this irregular shape, how to get started? This project is C++/CLR, based .net, either C# or C++/CLI idea are welcome.

void MouseDown(Object^ sender, MouseEventArgs^ e)
{
    selected_control = safe_cast<Control^>(sender);
    is_draging = true;
    drag_start_point = gcnew Point(e->X, e->Y);
    selected_control->Capture = true;
}

void MouseUp(Object^ sender, MouseEventArgs^ e)
{
    is_draging = false;
    selected_control->Capture = false;
}

void MouseMove(Object^ sender, MouseEventArgs^ e)
{
    if (is_draging)
    {
        selected_control->Left = Math::Max(0, e->X + selected_control->Left - drag_start_point->X);
        selected_control->Top = Math::Max(0, e->Y + selected_control->Top - drag_start_point->Y);
    }
}

Solution

  • OK, screwed up, CLI is not command line.

    To draw an irregular shape in Winforms, you'll use GraphicsPath. From the MS Docs:

    GraphicsPath path = new GraphicsPath();
    Pen penJoin = new Pen(Color.FromArgb(255, 0, 0, 255), 8);
    
    path.StartFigure();
    path.AddLine(new Point(50, 200), new Point(100, 200));
    path.AddLine(new Point(100, 200), new Point(100, 250));
    
    penJoin.LineJoin = LineJoin.Bevel;
    e.Graphics.DrawPath(penJoin, path);
    
    

    I.e. you'll draw the seven lines using path.AddLine to make your arrow shape.

    GraphicsPath.FillPath lets you fill the interior of a GraphicsPath with a brush.

    For resize, reshape, investigate the various GraphicsPath "transform" methods.

    For selection, you'll get the Region of the GraphicsPath, and determine if the mouse point intersects it.