它们是5个独立的矩形,一条直线和一个椭圆(wpf元素)。设置此选项后,我将计算大矩形的角点并保存它们。 我用Canvas.SetLeft和Canvas.SetTop定位整个内容。 现在,用户可以旋转此构造。 这是我的问题:旋转后如何为所有元素计算SetTop和SetLeft的正确值?我需要它们来计算旋转后发生的平移和调整大小的位置。
EDIT1
private Canvas
contentContainer;
private bool
isMoving = false,
isRotating = false,
isLoading = true,
isResizing = false,
needRotationCenterUpdate = true,
isInBounds = false,
isRedrawing = false;
/// <summary>
/// position of mouse cursor at buttondown event relative to map
/// </summary>
private Point
initialMoveScreenPosition;
/// <summary>
/// position of mouse cursor at buttondown event relative to surroundingRectangle
/// </summary>
private Point
initialMoveScreenOffset;
/// <summary>
/// map coordinates of initialMoveScreenPosition
/// </summary>
private LonLat
initialMoveMapPosition = null;
public Point
ConnectionLineDirection
{ get; set; }
private Point
rotationCenter,
cornerA,
cornerB,
cornerC,
cornerD,
activeCorner;
private MouseButtonEventHandler
selectHandler,
mouseDownHandler,
mouseUpHandler;
private MouseEventHandler
mouseMoveHandler;
private FrameworkElement
surroundingRectangle = null;
private LonLat
centerPosition,
northPosition;
private Ellipse
rotationSign;
private Line
connectionLine;
private Rectangle
resizeCorner1,
resizeCorner2,
resizeCorner3,
resizeCorner4,
activeResizeCorner;
private double
oldAngle,
angle,
distance,
rotationSignLeft = double.NaN,
rotationSignTop= double.NaN,
OrigOffsetLeft= double.NaN,
OrigOffsetTop= double.NaN;
public RotateTransform
rotateSurroundingRectangle,
rotateResizeCorner1,
rotateResizeCorner2,
rotateResizeCorner3,
rotateResizeCorner4,
rotateRotationSign;
this.mouseDownHandler = new MouseButtonEventHandler((s, a) =>
{
this.OrigOffsetLeft = Canvas.GetLeft(this.contentContainer);
this.OrigOffsetTop = Canvas.GetTop(this.contentContainer);
if (s.Equals(this.surroundingRectangle))
{
// Check, if the mouse interaction is a valid start of movement
if (this.ParentLayer != null && a.LeftButton == MouseButtonState.Pressed)// && !this.isMoving)
{
// Select this control
this.IsSelected = true;
// Element is now moved
this.isMoving = true;
this.isRotating = false;
this.isResizing = false;
// Get the initial move positions
this.initialMoveScreenPosition = a.GetPosition(this.ParentLayer);
this.initialMoveScreenOffset = a.GetPosition(this.surroundingRectangle);
this.initialMoveMapPosition = this.ParentLayer.GetPosition(this.initialMoveScreenPosition);
// Capture the mouse while dragging
this.surroundingRectangle.CaptureMouse();
// Mouse movement was handled
a.Handled = true;
// Remove the cursor
this.surroundingRectangle.Cursor = this.SetCursorDependingOnPosition();
}
}
else if (s.Equals(this.rotationSign))
{
if (this.ParentLayer != null && a.LeftButton == MouseButtonState.Pressed )
{
// Select this control
this.IsSelected = true;
this.isMoving = false;
this.isRotating = true;
this.isResizing = false;
// Get the initial move positions
this.initialMoveScreenPosition = a.GetPosition(this.ParentLayer);
this.initialMoveScreenOffset = a.GetPosition(this.surroundingRectangle);
this.initialMoveMapPosition = this.ParentLayer.GetPosition(this.initialMoveScreenPosition);
// Mouse movement was handled
this.rotationSign.CaptureMouse();
a.Handled = true;
}
}
else if (s.Equals(this.resizeCorner1) || s.Equals(this.resizeCorner2) || s.Equals(this.resizeCorner3) || s.Equals(this.resizeCorner4))
{
this.IsSelected = true;
this.isMoving = false;
this.isRotating = false;
this.isResizing = true;
this.initialMoveScreenPosition = a.GetPosition(this.ParentLayer);
this.initialMoveScreenOffset = a.GetPosition(this.surroundingRectangle);
this.initialMoveMapPosition = this.ParentLayer.GetPosition(this.initialMoveScreenPosition);
SetResizeCornerPosition();
this.SetActiveCorner();
a.Handled = true;
}
}
.mouseMoveHandler = new MouseEventHandler((s, a) =>
{
// Check, if the left button is pressed
if (this.ParentLayer != null && a.LeftButton == MouseButtonState.Pressed)
{
if (this.isMoving)
{
this.Move(a);
}
else if (this.isResizing)
{
this.Resize(a);
}
else if (this.isRotating)
{
this.Rotate(a);
}
}
else
{
// Mouse is no longer moved
this.isMoving = false;
// Stop capturing the mouse
this.surroundingRectangle.ReleaseMouseCapture();
// Remove the cursor
this.surroundingRectangle.Cursor = this.SetCursorDependingOnPosition();
}
}
.mouseUpHandler = new MouseButtonEventHandler((s, a) =>
{
if (a.LeftButton != MouseButtonState.Pressed)
{
// Check, if the left button is released
if (this.isMoving)
{
// Mouse is no longer moved
this.isMoving = false;
this.isResizing = false;
this.isRotating = false;
this.activeCorner = this.rotationCenter;
// Stop capturing the mouse
this.surroundingRectangle.ReleaseMouseCapture();
// Remove the cursor
this.surroundingRectangle.Cursor = this.SetCursorDependingOnPosition();
}
}
}
private void Rotate(MouseEventArgs e)
if (e.LeftButton == MouseButtonState.Pressed)
{
// Get the current screen and map position
Point currentScreenPosition = e.GetPosition(this.ParentLayer);
// Calculate orientation and distance
this.northPosition = this.ParentLayer.GetPosition(currentScreenPosition);
this.oldAngle = angle;
this.angle = this.centerPosition.AngleTo(this.northPosition);
this.distance = this.centerPosition.DistanceTo(this.northPosition);
// Handle the change of the bounds
this.HandleBoundsChanged();
// Allow the extending methods to handle the change of the location
this.HandleLocationChanged();
// Raise event
if (this.LoacationChanged != null) this.LoacationChanged(this, null);
// Avoid other mouse events
e.Handled = true;
}
else
{
// Select this control
this.IsSelected = true;
// Element is now moved
// Get the initial move positions
this.initialMoveScreenPosition = e.GetPosition(this.ParentLayer);
this.initialMoveScreenOffset = e.GetPosition(this.rotationSign);
this.initialMoveMapPosition = this.ParentLayer.GetPosition(this.initialMoveScreenPosition);
e.Handled = true;
}
}
private void Move(MouseEventArgs a)
{
// Get change in x and y direction
double moveX = a.GetPosition(this.ParentLayer).X - this.initialMoveScreenPosition.X;
double moveY = a.GetPosition(this.ParentLayer).Y - this.initialMoveScreenPosition.Y;
//set the new positions
this.rotationCenter.X += moveX;
this.rotationCenter.Y += moveY;
this.needRotationCenterUpdate = true;
this.OrigOffsetLeft += moveX;
this.OrigOffsetTop += moveY;
this.rotationSignLeft += moveX;
this.rotationSignTop += moveY;
this.cornerA.X += moveX;
this.cornerA.Y += moveY;
this.cornerB.X += moveX;
this.cornerB.Y += moveY;
this.cornerC.X += moveX;
this.cornerC.Y += moveY;
this.cornerD.X += moveX;
this.cornerD.Y += moveY;
this.ConnectionLineDirection = new Point(this.ConnectionLineDirection.X + moveX, this.ConnectionLineDirection.Y + moveY);
this.needRotationCenterUpdate = true;
this.HandleCenterPositionChanged(this.rotationCenter);
// Refresh the position of this control and raise event
this.HandleBoundsChanged();
if (this.LoacationChanged != null) this.LoacationChanged(this, null);
this.initialMoveScreenPosition = a.GetPosition(this.ParentLayer);
this.initialMoveScreenOffset = a.GetPosition(this.rotationSign);
this.initialMoveMapPosition = this.ParentLayer.GetPosition(this.initialMoveScreenPosition);
// Avoid other mouse events
a.Handled = true;
// Remove the cursor
this.surroundingRectangle.Cursor = this.SetCursorDependingOnPosition();
}
private void Resize(MouseEventArgs a)
{
if(a.LeftButton == MouseButtonState.Pressed)
{
Point mousepos = a.GetPosition(this.ParentLayer);
double moveX = Math.Abs(this.initialMoveScreenPosition.X - mousepos.X);
double moveY = Math.Abs(this.initialMoveScreenPosition.Y - mousepos.Y);
double move = moveX > moveY ? moveX : moveY;
double width;
double height;
//if (this.angle != 0)
//{
// ReturnToStandartCase();
//}
double dis1 = this.rotationCenter.CalculateDistance(mousepos) + this.initialMoveScreenPosition.CalculateDistance(this.activeCorner);
double dis2 = this.rotationCenter.CalculateDistance(this.activeCorner);
if (dis1 < dis2)
{
width = this.contentContainer.Width - move;
height = this.contentContainer.Height - move;
if (width > 3 * resizeCornerSize)
{
this.contentContainer.Width = width;
this.contentContainer.Height = height;
this.OrigOffsetLeft += move/2;
this.OrigOffsetTop += move/2;
this.rotationSignTop += move/2;
}
}
else
{
width = this.contentContainer.Width + move;
height = this.contentContainer.Height + move;
if (width > 3 * resizeCornerSize)
{
this.contentContainer.Width = width;
this.contentContainer.Height = height;
this.OrigOffsetLeft -= move/2;
this.OrigOffsetTop -= move/2;
this.rotationSignTop -= move / 2;
}
}
//Logger.Logger.Write("C:\\Users\\Maik\\Desktop\\coord.log", "Top,Left,Bottom,Right: " + Canvas.GetTop(this.contentContainer) + " ; " + Canvas.GetLeft(this.contentContainer) + " ; " + Canvas.GetBottom(this.contentContainer) + " ; " + Canvas.GetRight(this.contentContainer));
this.HandleResize(this.contentContainer.Width, this.contentContainer.Height);
this.HandleBoundsChanged();
// Allow the extending methods to handle the change of the location
this.HandleLocationChanged();
this.initialMoveScreenPosition = a.GetPosition(this.ParentLayer);
this.initialMoveScreenOffset = a.GetPosition(this.rotationSign);
this.initialMoveMapPosition = this.ParentLayer.GetPosition(this.initialMoveScreenPosition);
// Raise event
if (this.LoacationChanged != null) this.LoacationChanged(this, null);
a.Handled = true;
}
else
{
// Select this control
this.IsSelected = true;
// Element is now moved
// Get the initial move positions
this.initialMoveScreenPosition = a.GetPosition(this.ParentLayer);
this.initialMoveScreenOffset = a.GetPosition(this.rotationSign);
this.initialMoveMapPosition = this.ParentLayer.GetPosition(this.initialMoveScreenPosition);
a.Handled = true;
}
}
public override void HandleBoundsChanged()
{
// Check, if the center position is defined
if (this.centerPosition != null && this.ParentLayer != null )
{
// Get the position of this element on the parent screen
Point centerPositionOnScreen = this.ParentLayer.GetPosition(this.centerPosition);
this.HandleCenterPositionChanged(centerPositionOnScreen);
// Make the content container become visible
if (this.contentContainer.Visibility != Visibility.Visible) this.contentContainer.Visibility = Visibility.Visible;
// Calculate the bounds of this element on the screen
double halfwidth;
double halfheight;
if (double.IsNaN(this.OrigOffsetLeft))
{
halfwidth = this.contentContainer.Width / 2;
halfheight = this.contentContainer.Height / 2;
this.OrigOffsetLeft = centerPositionOnScreen.X - halfwidth;
//this.OrigOffsetTop = centerPositionOnScreen.X + halfwidth;
this.OrigOffsetTop = centerPositionOnScreen.Y - halfheight;
//y1 = centerPositionOnScreen.Y + halfheight;
}
// Locate the content container on the screen
Canvas.SetLeft(this.contentContainer, this.OrigOffsetLeft);
Canvas.SetTop(this.contentContainer, this.OrigOffsetTop);
Canvas.SetRight(this.contentContainer, this.ParentLayer.Width - (this.OrigOffsetLeft + this.contentContainer.Width));
Canvas.SetBottom(this.contentContainer, this.ParentLayer.Width - (this.OrigOffsetTop + this.contentContainer.Height));
// Check, if the move overlay needs to be set
if (this.IsSelected)
{
// Make sure, the selection is visible
this.EnsureSeclectionAdded();
// Locate the surrounding rectangle
Canvas.SetLeft(this.surroundingRectangle, this.OrigOffsetLeft);
Canvas.SetTop(this.surroundingRectangle, this.OrigOffsetTop);
//Canvas.SetRight(this.surroundingRectangle, this.ParentLayer.Width - x1);
//Canvas.SetBottom(this.surroundingRectangle, this.ParentLayer.Width - y1);
this.surroundingRectangle.Width = this.contentContainer.Width;
this.surroundingRectangle.Height = this.contentContainer.Height;
if (this.ConnectionLineDirection.X == -1 || this.ConnectionLineDirection.Y == -1)
{
this.SetCornerPoints();
}
if (this.isLoading)
{
this.SetResizeCorners();
this.rotationCenter = this.cornerA.CalculatePointOnLine(this.cornerC, 0.5);
this.SetConnectionLine();
this.SetRotationSign();
//this.rotationTest();
this.isLoading = false;
}
if (isRotating)
{
// Refresh the rotation transform
if (this.needRotationCenterUpdate)
{
this.RefreshRotationCenter();
this.needRotationCenterUpdate = false;
}
this.rotateSurroundingRectangle.Angle = this.angle;
this.rotateResizeCorner1.Angle = this.angle;
this.rotateResizeCorner2.Angle = this.angle;
this.rotateResizeCorner3.Angle = this.angle;
this.rotateResizeCorner4.Angle = this.angle;
this.rotateRotationSign.Angle = this.angle;
this.RotateCornerPoints();
this.SetConnectionLine();
if (this.LoacationChanged != null) this.LoacationChanged(this, null);
}
if (this.isMoving)
{
//this.SetCornerPoints();
this.SetResizeCorners();
this.SetConnectionLine();
this.SetRotationSign();
if (this.LoacationChanged != null) this.LoacationChanged(this, null);
}
if (this.isResizing)
{
this.SetCornerPoints();
this.SetResizeCorners();
this.SetConnectionLine();
this.SetRotationSign();
}
}
else
{
// Make sure, the selection is removed
this.EnsureSelectionRemoved();
// Movement is disabled
this.isMoving = false;
}
}
else
{
// Hide the content container from the parent element
if (this.contentContainer.Visibility != Visibility.Hidden) this.contentContainer.Visibility = Visibility.Hidden;
// Make sure, the selection is removed
this.EnsureSelectionRemoved();
// Movement is disabled
this.isMoving = false;
}
}
我不太确定这是否是所有重要的代码。是的,我知道此代码还有其他问题。一旦我知道了定位问题的方向,我将予以纠正。