c wpf 3d drawing a hollow rectangle
This example shows how you tin can let the user motion and resize a Rectangle object at run time in a WPF program. The plan'due south XAML code defines a Canvass object that contains the Rectangle. The program catches the Canvas object's MouseDown, MouseMove, and MouseUp events. One oddity of this is that the Canvass must have a non-null background to get in generate mouse events. In this case, I set its groundwork to Transparent so it's however invisible, merely it'due south not null.
The program uses the following code to track the resizing functioning.
// The part of the rectangle the mouse is over. private enum HitType { None, Body, UL, UR, LR, LL }; // The part of the rectangle nether the mouse. HitType MouseHitType = HitType.None; // True if a elevate is in progress. individual bool DragInProgress = false; // The drag'southward last point. private Indicate LastPoint;
The HitType enumeration indicates parts of the rectangle. The variable MouseHitType indicates the office of the rectangle under the mouse at various times. The variable DragInProgress is truthful when the user is moving or resizing the rectangle. LastPoint is the concluding recorded position of the mouse during a drag.
The plan uses two helper methods. The SetHitType method shown in the post-obit code returns a HitType value to indicate what part of the rectangle is below the mouse.
// Render a HitType value to signal what is at the betoken. private HitType SetHitType(Rectangle rect, Bespeak signal) { double left = Sail.GetLeft(rectangle1); double peak = Canvas.GetTop(rectangle1); double right = left + rectangle1.Width; double lesser = height + rectangle1.Meridian; if (point.10 < left) return HitType.None; if (point.X > right) return HitType.None; if (point.Y < top) return HitType.None; if (bespeak.Y > bottom) return HitType.None; const double GAP = 10; if (point.Ten - left < GAP) { // Left border. if (bespeak.Y - height < GAP) render HitType.UL; if (lesser - signal.Y < GAP) return HitType.LL; render HitType.L; } else if (right - point.X < GAP) { // Right border. if (point.Y - peak < GAP) return HitType.UR; if (lesser - betoken.Y < GAP) return HitType.LR; return HitType.R; } if (bespeak.Y - meridian < GAP) return HitType.T; if (bottom - indicate.Y < GAP) return HitType.B; return HitType.Body; }
This method uses the Canvas course'southward GetLeft and GetTop methods to get the rectangle's left and summit coordinates. (The instance assumes you set those values for the rectangle.) Those are attached properties provided by the Canvass control for the Rectangle control, then you demand to utilize the Sail command's methods to go and set their values.
The lawmaking first compares the left and top values to the rectangle's edges. If the mouse lies outside of the rectangle, the method returns None.
Next the code uses the mouse's coordinates and the rectangle'south coordinates to make up one's mind whether the mouse is over a rectangle corner, edge, or body, and it returns the correct HitType.
The following code shows the SetMouseCursor helper method.
// Set a mouse cursor appropriate for the current hit type. private void SetMouseCursor() { // See what cursor we should display. Cursor desired_cursor = Cursors.Pointer; switch (MouseHitType) { case HitType.None: desired_cursor = Cursors.Arrow; break; case HitType.Body: desired_cursor = Cursors.ScrollAll; intermission; case HitType.UL: case HitType.LR: desired_cursor = Cursors.SizeNWSE; break; case HitType.LL: example HitType.UR: desired_cursor = Cursors.SizeNESW; break; example HitType.T: case HitType.B: desired_cursor = Cursors.SizeNS; break; instance HitType.L: case HitType.R: desired_cursor = Cursors.SizeWE; break; } // Display the desired cursor. if (Cursor != desired_cursor) Cursor = desired_cursor; }
This lawmaking simply sets the cursor that is appropriate for the mouse's hit type.
The following lawmaking executes when the user presses the mouse down over the Canvas.
// Outset dragging. private void canvas1_MouseDown(object sender, MouseButtonEventArgs due east) { MouseHitType = SetHitType(rectangle1, Mouse.GetPosition(canvas1)); SetMouseCursor(); if (MouseHitType == HitType.None) render; LastPoint = Mouse.GetPosition(canvas1); DragInProgress = true; }
This method calls SetHitType to see whether the mouse is over the rectangle. If it is not, the method returns.
Otherwise the method saves the mouse'south current location in the LastPoint variable and sets DragInProgress to truthful.
When the user moves the mouse, the following lawmaking executes.
// If a drag is in progress, continue the drag. // Otherwise brandish the right cursor. private void canvas1_MouseMove(object sender, MouseEventArgs east) { if (DragInProgress) { // See how much the mouse has moved. Bespeak point = Mouse.GetPosition(canvas1); double offset_x = point.Ten - LastPoint.10; double offset_y = point.Y - LastPoint.Y; // Get the rectangle'due south current position. double new_x = Canvas.GetLeft(rectangle1); double new_y = Canvas.GetTop(rectangle1); double new_width = rectangle1.Width; double new_height = rectangle1.Meridian; // Update the rectangle. switch (MouseHitType) { case HitType.Body: new_x += offset_x; new_y += offset_y; intermission; example HitType.UL: new_x += offset_x; new_y += offset_y; new_width -= offset_x; new_height -= offset_y; break; case HitType.UR: new_y += offset_y; new_width += offset_x; new_height -= offset_y; break; case HitType.LR: new_width += offset_x; new_height += offset_y; break; example HitType.LL: new_x += offset_x; new_width -= offset_x; new_height += offset_y; break; case HitType.L: new_x += offset_x; new_width -= offset_x; break; case HitType.R: new_width += offset_x; interruption; case HitType.B: new_height += offset_y; break; case HitType.T: new_y += offset_y; new_height -= offset_y; break; } // Don't use negative width or pinnacle. if ((new_width > 0) && (new_height > 0)) { // Update the rectangle. Canvas.SetLeft(rectangle1, new_x); Canvas.SetTop(rectangle1, new_y); rectangle1.Width = new_width; rectangle1.Height = new_height; // Salve the mouse's new location. LastPoint = betoken; } } else { MouseHitType = SetHitType(rectangle1, Mouse.GetPosition(canvas1)); SetMouseCursor(); } }
This code does one of two things depending on whether a drag is in progress.
If a drag is not in progress, the method calls SetHitType to meet whether the mouse is over the rectangle and SetMouseCursor to display an appropriate cursor.
If a elevate is in progress, the code gets the mouse's current position and subtracts its coordinates from LastPoint to run across how far the mouse has moved since that point was recorded. It gets the rectangle's current position, and then initializes variables to hold the rectangle's new size and position.
Then depending on the role of the rectangle that was under the mouse, the method updates the rectangle's new size and position.
The method ensures that the rectangle's new width and height aren't less than 0, and it updates the rectangle's size and position. Finally the code saves the mouse's current location for next fourth dimension.
The following code shows the last piece of the program.
// Stop dragging. private void canvas1_MouseUp(object sender, MouseButtonEventArgs e) { DragInProgress = false; }
This code simply stops the drag.
Source: http://csharphelper.com/blog/2014/12/let-user-move-resize-rectangle-wpf-c/
0 Response to "c wpf 3d drawing a hollow rectangle"
Post a Comment