在Rectangle c#

时间:2016-02-03 08:15:43

标签: c# wpf shape mousemove mouse-position

当我通过拖动CanvasMouse上画一条线时,我必须向Lines的孩子添加Canvas而不是添加当前位置Mouse - 我猜这是因为Mouse的移动速度比Rendering的{​​{1}}快。

我创建了一个新的Canvas类,它继承自BoundingBox并实现了Shape属性。这个新的DefiningGeometry包含ShapeRectangle

IShapeBase:

Text

BoudingBox:

public abstract class IShapeBase : Shape
{
    public uint Id { get; set; }
    public bool ShapeReady { get; set; }
    public Point Location { get; set; }
    public Brush Color { get; set; }
    public string Text { get; set; }
    public bool OnResizing { get; set; }
    public bool OnMoving { get; set; }

    protected IShapeBase() { ShapeReady = false; }
    public abstract bool IsInBounds(Point currentLocation);
}

我想确保public class BoundingBox : IShapeBase { private enum ResizeDirection { None, Top, Left, Bottom, Right, TopLeft, TopRight, BottomRight, BottomLeft } private PathGeometry m_pathGeometry; private RectangleGeometry m_rectangleGeometry; private Geometry m_textGeometry; private Point m_downClick = new Point(-1, -1); private Point m_previousLocation = new Point(-1, -1); private Rect m_rectangle; private ResizeDirection m_resizeDirection = ResizeDirection.None; protected override Geometry DefiningGeometry { get { var formattedText = new FormattedText(Text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Times New-Roman"), 14, Brushes.Transparent); var chosenTextPoint = new Point { X = ((Location.X < BottomRight.X) ? Location.X : BottomRight.X) + 5, Y = ((Location.Y < BottomRight.Y) ? Location.Y : BottomRight.Y) + 5 }; Stroke = Color; StrokeThickness = IsMouseDirectlyOver ? 1.5 : 1; m_rectangle = new Rect(Location, BottomRight); m_pathGeometry = new PathGeometry(); m_rectangleGeometry = new RectangleGeometry(m_rectangle); m_textGeometry = formattedText.BuildGeometry(chosenTextPoint); m_pathGeometry.AddGeometry(m_rectangleGeometry); m_pathGeometry.AddGeometry(m_textGeometry); Fill = Brushes.Transparent; return m_pathGeometry; } } public Point BottomRight { get; set; } public Rect Rectangle { get { return m_rectangle; } } private void CheckHowToResize(Point currentLocation) { var currentTopLeft = m_rectangle.TopLeft; var currentBottomRight = m_rectangle.BottomRight; if (m_resizeDirection != ResizeDirection.None) return; if ((currentLocation.X >= currentTopLeft.X - 5) && (currentLocation.X <= currentTopLeft.X + 5)) m_resizeDirection = ((currentLocation.Y >= currentBottomRight.Y - 5) && (currentLocation.Y <= currentBottomRight.Y + 5)) ? ResizeDirection.BottomLeft : ResizeDirection.Left; if ((currentLocation.Y >= currentTopLeft.Y - 5) && (currentLocation.Y <= currentTopLeft.Y + 5)) m_resizeDirection = (m_resizeDirection == ResizeDirection.Left) ? ResizeDirection.TopLeft : ResizeDirection.Top; if ((currentLocation.X >= currentBottomRight.X - 5) && (currentLocation.X <= currentBottomRight.X + 5)) m_resizeDirection = (m_resizeDirection == ResizeDirection.Top) ? ResizeDirection.TopRight : ResizeDirection.Right; if ((currentLocation.Y >= currentBottomRight.Y - 5) && (currentLocation.Y <= currentBottomRight.Y + 5) && (m_resizeDirection != ResizeDirection.BottomLeft)) m_resizeDirection = (m_resizeDirection == ResizeDirection.Right) ? ResizeDirection.BottomRight : ResizeDirection.Bottom; if (m_resizeDirection != ResizeDirection.None) OnResizing = true; } private void Resize(Point currentLocation) { switch (m_resizeDirection) { case ResizeDirection.Left: { Location = new TranslateTransform(currentLocation.X - Location.X, 0).Transform(Location); Mouse.OverrideCursor = Cursors.SizeWE; break; } case ResizeDirection.Top: { Location = new TranslateTransform(0, currentLocation.Y - Location.Y).Transform(Location); Mouse.OverrideCursor = Cursors.SizeNS; break; } case ResizeDirection.TopLeft: { Location = new TranslateTransform(currentLocation.X - Location.X, currentLocation.Y - Location.Y).Transform(Location); Mouse.OverrideCursor = Cursors.SizeNWSE; break; } case ResizeDirection.Right: { BottomRight = new TranslateTransform(currentLocation.X - BottomRight.X, 0).Transform(BottomRight); Mouse.OverrideCursor = Cursors.SizeWE; break; } case ResizeDirection.Bottom: { BottomRight = new TranslateTransform(0, currentLocation.Y - BottomRight.Y).Transform(BottomRight); Mouse.OverrideCursor = Cursors.SizeNS; break; } case ResizeDirection.BottomRight: { BottomRight = new TranslateTransform(currentLocation.X - BottomRight.X, currentLocation.Y - BottomRight.Y).Transform(BottomRight); Mouse.OverrideCursor = Cursors.SizeNWSE; break; } case ResizeDirection.TopRight: { Location = new TranslateTransform(0, currentLocation.Y - Location.Y).Transform(Location); BottomRight = new TranslateTransform(currentLocation.X - BottomRight.X, 0).Transform(BottomRight); Mouse.OverrideCursor = Cursors.SizeNESW; break; } case ResizeDirection.BottomLeft: { Location = new TranslateTransform(currentLocation.X - Location.X, 0).Transform(Location); BottomRight = new TranslateTransform(0, currentLocation.Y - BottomRight.Y).Transform(BottomRight); Mouse.OverrideCursor = Cursors.SizeNESW; break; } } } public override bool IsInBounds(Point currentLocation) { return ((currentLocation.X >= m_rectangle.Left - 2) && (currentLocation.X <= m_rectangle.Right + 2) && (currentLocation.Y >= m_rectangle.Top - 2) && (currentLocation.Y <= m_rectangle.Bottom + 2)); } protected override void OnMouseDown(MouseButtonEventArgs e) { Mouse.Capture(this); if (e.LeftButton == MouseButtonState.Pressed) m_downClick = e.GetPosition(this); } protected override void OnMouseMove(MouseEventArgs e) { if (e.LeftButton != MouseButtonState.Pressed) return; Thread.Sleep(20); var currentLocation = e.GetPosition(this); if (!OnMoving) { CheckHowToResize(currentLocation); if (OnResizing) { Resize(currentLocation); return; } } m_pathGeometry.Transform = new TranslateTransform((currentLocation.X - m_downClick.X), (currentLocation.Y - m_downClick.Y)); Mouse.OverrideCursor = Cursors.ScrollAll; OnMoving = true; m_previousLocation = currentLocation; } protected override void OnMouseUp(MouseButtonEventArgs e) { m_downClick = new Point(-1, -1); ReleaseMouseCapture(); OnResizing = false; OnMoving = false; m_resizeDirection = ResizeDirection.None; Location = m_pathGeometry.Transform.Transform(Location); BottomRight = m_pathGeometry.Transform.Transform(BottomRight); } protected override void OnIsMouseDirectlyOverChanged(DependencyPropertyChangedEventArgs e) { StrokeThickness = IsMouseDirectlyOver ? 1.5 : 1; } } 只能在BoudningBox的边界移动。

目前,由于我从外部使用Canvas,因此我可以限制ClipCursorShape边界的创建和调整大小,但如果我尝试通过单击Canvas的中心并拖动它来移动它,然后我可以移动它直到鼠标到达Shape的边界,但CanvasShape的一半1}}和半外。

我的主要困难是检测Canvas到达MouseShape边界的确切时间,因为(我再次猜测)Canvasrendering慢于Mouse的移动。

这会影响我正在尝试实施的所有内容:

1)当鼠标在它上面时突出显示BoundingBox

2)根据Mouse当前位置下方的内容,将Mouse的光标更改为滚动/调整大小/箭头。

3)将BoundinBox移到其parent画布的边界内。

可以达到这样的准确度吗?

1 个答案:

答案 0 :(得分:0)

  • 为Canvas(容器)
  • 定义边框矩形
  • 获取四个边界框(儿童角点)
  • 在移动边界框之前,请检查角落是否位于容器中
  • 您可以在移动前使用translateTransform.Transform(point)
  • 您可以使用Rect的Contains方法检查点是否位于
  • 之内
  • 仅当所有4个角都在
  • 范围内时才应用变换