WPF uses Canvas to draw a variable rectangle and wpfcanvas to draw a rectangle.

Source: Internet
Author: User

WPF uses Canvas to draw a variable rectangle and wpfcanvas to draw a rectangle.
1. Problems and Solutions

Recently, a location verification function is required for the project. The general requirement is as follows: there is an image with some location information, but the location information may be slightly different from the actual one, you need to make a simple adjustment, and then cut the image and perform some processing. (Location information is a small rectangle .)

The general idea for solving the above problems is as follows: Use canvas to draw images as the canvas background and draw rectangles on the canvas. Like qq, you can drag the rectangle to adjust the size of the rectangle. Then, write down the modified position and provide it to the image after cutting. At present, the key problem is to implement a rectangle that can be dragged like qq.

2. effect Preview


The above is the effect of the demo. It mainly consists of positioning points and connections.

3. Variable rectangle implementation
  1. Positioning point
    The positioning point is mainly used to describe the small box on the rectangle. The mouse drag event is triggered by it, and the movement of its position is linked to the movement of the relevant line.


Positioning points are the basic attributes and methods of positioning points, including the painting method and moving method.
AnchorPointType indicates the positioning point type;

Public enum AnchorPointType {// <summary> /// up/down // </summary> NS, /// <summary> /// left and right /// </summary> WE, /// <summary> /// top right /// </summary> NE, /// <summary> /// bottom left /// </summary> SW, /// <summary> /// bottom right /// </summary> NW, /// <summary> /// top left /// </summary> SE}

The draw () method is used to draw a rectangle:

        public Rectangle Draw()         {            double offset = this.Width / 2;            Rectangle retc = new Rectangle()            {                Margin = new Thickness(this.X - offset, this.Y - offset, 0, 0),                Width = this.Width,                Height = this.Height,                Fill = Brushes.LightGoldenrodYellow,                Stroke = Brushes.Black,                StrokeThickness = 1,                DataContext = this.Key            };            this.retc = retc;            return retc;        }

Move ()

        public void Move(double x,double y)        {            double offset = this.Width / 2;            this.retc.Margin = new Thickness(x-offset,y-offset,0,0);            this.X = x;            this.Y = y;        }
  1. Variable rectangle
    This part mainly implements the rectangle drawing function. The main code is as follows:
    Public void Init () {// category by X axis IEnumerable <IGrouping <double, Point> pointXs = points. groupBy (o => o. x); // IEnumerable <IGrouping <double, Point> pointYs = points by week. groupBy (o => o. y); // draw a vertical line DrawXLine (pointXs); // draw a horizontal line DrawYLine (pointYs); // set the positioning point AddAnchorPoints (); // draw the positioning point and add the event foreach (AnchorPoint anchorPoint in anchorPoints) {Rectangle rec = anchorPoint. draw (); rec. mouseLeftButtonDown + = new MouseButtonEventHandler (rec_MouseLeftButtonDown); rec. mouseMove + = new MouseEventHandler (rec_MouseMove); canvas. children. add (rec);} // canvas Add event canvas. mouseLeftButtonUp + = new MouseButtonEventHandler (canvas_MouseLeftButtonUp); canvas. mouseMove + = new MouseEventHandler (canvas_MouseMove); canvas. mouseLeave + = new MouseEventHandler (canvas_MouseLeave );}
    Code above:
    Code above:
    1. Category by X axis and Y axis
    2. Draw a vertical line and a horizontal line
    3. Set the positioning point
    4. Draw positioning points and add event listening
    5. Add events to the canvas
    Add the mouse MouseMove and MouseLeftButtonDown events to each positioning point, and add the MouseMove, MouseLeave, and MouseLeftButtonUp events to the canvas.
    The specific code is not pasted. If you need code, you can download the source code.
  2. Rectangular line linkage
    A rectangular line is associated with a vertex line. It determines whether the line is associated with a dynamic point to link the related line. The main code is as follows:
         private void MoveLines(double x, double y)     {         List<Line> moveLines = new List<Line>();         moveLines = lines.Where(o => o.Y1 == curAnchorPoint.Y             || o.Y2 == curAnchorPoint.Y             || o.X1 == curAnchorPoint.X             || o.X2 == curAnchorPoint.X).ToList();         foreach (Line line in moveLines)         {             if (line.Y1 == curAnchorPoint.Y)             {                 line.Y1 = y;             }             if (line.Y2 == curAnchorPoint.Y)             {                 line.Y2 = y;             }             if (line.X1 == curAnchorPoint.X)             {                 line.X1 = x;             }             if (line.X2 == curAnchorPoint.X)             {                 line.X2 = x;             }         }     }
  3. Linkage of positioning points

Point linkage is similar to the line linkage method, but the point linkage is more complex than the line linkage, mainly in the following three aspects: 1. Point movement requires the linkage of the midpoint. 2. When the four vertices of the rectangle change, the other two adjacent vertices need to be linked to the midpoint of the two adjacent lines. 3. There will be a lot of if else.
Because the code is long, it is not pasted. You can obtain the source code from the source code.
Line midpoint linkage: determines whether the moving vertex is associated with two or one vertex in the calculation of the midpoint. If the two vertices associated with the midpoint change, then the midpoint needs to be changed. The main code is as follows:

        private void MoveRefAnchorPoint(double x, double y,AnchorPoint movedAnchorPoint)        {            foreach (AnchorPoint anchorPoint in anchorPoints)            {                if (anchorPoint.RefPoint.Length == 2)                {                    if (anchorPoint.RefPoint[0].X == x && anchorPoint.RefPoint[0].Y == y)                    {                        anchorPoint.RefPoint[0].X = movedAnchorPoint.X;                        anchorPoint.RefPoint[0].Y = movedAnchorPoint.Y;                    }                    else if (anchorPoint.RefPoint[1].X == x && anchorPoint.RefPoint[1].Y == y)                    {                        anchorPoint.RefPoint[1].X = movedAnchorPoint.X;                        anchorPoint.RefPoint[1].Y = movedAnchorPoint.Y;                    }                    anchorPoint.X = (anchorPoint.RefPoint[0].X + anchorPoint.RefPoint[1].X) / 2;                    anchorPoint.Y = (anchorPoint.RefPoint[0].Y + anchorPoint.RefPoint[1].Y) / 2;                    anchorPoint.Move();                }            }        }

The code above shows the change of a single link. The code that changes both links is similar to this one.

4. Obtain the source code

Due to the limited text expression ability, it is difficult to clarify the relationship between vertices and lines, especially the interaction between vertices and lines. If you are interested, you are strongly advised to download the code for debugging and reading.
Https://github.com/wangyan9110/ProjectDemos/tree/master/WPFCanvasDemo



How does a WPF Canvas dynamically adjust the layout when the program is running?

Canvas is definitely positioned. You should select Grid to meet your needs.

Wpf Implementation drawing with mouse

If it is Canvas, you can try it like this:
Use the Canvas_PreviewMouseLeftButtonDown event to record the coordinates of mouse clicks through event parameter e (for example, add a private field: lineStartPoint in the window class), and prepare a switch variable (for example, you can name it: isDrawingLine) is set to true.
Then, in the Canvas_PreviewMouseLeftButtonUp event, check this toggle variable. Once the variable is found to be true, take the coordinates of the mouse pointer (which can be called lineEndPoint). Compare the two coordinates, draw a line. You can create a Line Object and add it to Canvas. Children, and then set its X1/Y1/X2/Y2. After the Line is drawn, the true value of the switch field is immediately canceled.
This method should be able to draw a line, but it is not exactly what you need and I am not sure.
In this process, if you want to see the dynamic effect, you can also consider the Canvas_MouseMove event to take the coordinates instead of Canvas_PreviewMouseLeftButtonUp (but note that you only add Line once );
Canvas_PreviewMouseLeftButtonUp is used to cancel the true value of the switch variable and end the drawing.
If you pay attention to the details, you can add the Canvas_MouseLeave event to cancel the true value of the field and end the painting.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.