当我通过拖动Canvas
在Mouse
上画一条线时,我必须向Lines
的孩子添加Canvas
而不是添加当前位置Mouse
- 我猜这是因为Mouse
的移动速度比Rendering
的{{1}}快。
我创建了一个新的Canvas
类,它继承自BoundingBox
并实现了Shape
属性。这个新的DefiningGeometry
包含Shape
和Rectangle
:
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
,因此我可以限制ClipCursor
到Shape
边界的创建和调整大小,但如果我尝试通过单击Canvas
的中心并拖动它来移动它,然后我可以移动它直到鼠标到达Shape
的边界,但Canvas
是Shape
的一半1}}和半外。
我的主要困难是检测Canvas
到达Mouse
或Shape
边界的确切时间,因为(我再次猜测)Canvas
是rendering
慢于Mouse
的移动。
这会影响我正在尝试实施的所有内容:
1)当鼠标在它上面时突出显示BoundingBox
。
2)根据Mouse
当前位置下方的内容,将Mouse
的光标更改为滚动/调整大小/箭头。
3)将BoundinBox
移到其parent
画布的边界内。
可以达到这样的准确度吗?
答案 0 :(得分:0)
translateTransform.Transform(point)
Contains
方法检查点是否位于