2016-02-03 11 views
0

Когда я рисую линию на Canvas путем перетаскивания Mouse, я должен добавить Lines для детей Canvas «s, а не добавить текущую позицию Mouse - Я думаю, что это вызвано, так как Mouse Движение происходит быстрее, чем RenderingCanvas.Изменение курсора внутри прямоугольника с #

Я создал новый класс BoundingBox, который наследует от Shape и реализует собственность DefiningGeometry. Этот новый Shape состоит из Rectangle и Text:

IShapeBase:

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); 
} 

BoudingBox:

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 «s, но если я пытаюсь переместить его, нажав на центр Shape и перетаскивая его, тогда я могу переместить его, пока мышь не достигнет границ Canvas, но Shape находится наполовину на Canvas и наполовину снаружи.

Моя главная трудность обнаружения, когда именно делает Mouse удар либо Shape или границ Canvas»потому, что (опять же, я думаю) rendering медленнее, чем движение Mouse.

Это влияет на все, что я пытаюсь реализовать:

1), подчеркивающие BoundingBox при наведении курсора мыши на нем.

2) Изменение курсора Mouse для прокрутки/изменения размера/стрелки в зависимости от того, что находится под текущим местоположением Mouse.

3) Переместить BoundinBox в пределах его parent Холст`.

Можно ли достичь такой точности?

ответ

0
  • Определить границы-прямоугольник для Canvas (контейнера)
  • Получить четыре ограничительных рамки (ребенок) угловые точки
  • Перед перемещением рамки, проверьте углы будут лежать в контейнере
  • Вы можете использовать translateTransform.Transform(point) перед перемещением
  • Вы можете использовать Contains метод Rect, чтобы проверить, если точка находится в пределах
  • Нанести преобразование только если все 4 угла находятся в пределах
+0

Я пробовал все то, что вы написали с помощью системы осей «Холст» (отметьте между 0 и 'CanvasWidth' для координат' X' и между 0 и 'CanvasHeight' для координат' Y'). Это не сработало, движение не было гладким. Считаете ли вы, что добавление прямоугольника границы будет отличаться? – Idanis

+0

Посмотрите, помогает ли использование RenderTransform. – Makubex