WPF:如何翻译变形矩形?

时间:2015-10-13 16:07:34

标签: c# wpf

我试图通过鼠标移动在Canvas中绘制的矩形(拖放)。

当我点击矩形并将鼠标移动(继续点击)到新位置Pic1时。没关系。但当我再次点击它并将鼠标移动一点Pic2时,矩形移动到旧位置。

我不知道为什么会这样。谁能给我一些解释?

这是我的代码(所有参数都已分配并初始化)。 提前谢谢!

private void MyCanvas_MouseMove_1(object sender, MouseEventArgs e)
        { 
            if (e.RightButton == MouseButtonState.Pressed && e.OriginalSource is Shape)
            {
                p2 = e.GetPosition(MyCanvas);
                TranslateTransform tf = new TranslateTransform(p2.X - p1.X, p2.Y - p1.Y);
                _MyTestRect.RenderTransform = tf;
            }

        }
private void MyCanvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {

            if (e.OriginalSource is Shape)
            {
                p1 = e.GetPosition(MyCanvas);
            }

        }

3 个答案:

答案 0 :(得分:0)

每次重置翻译时都不应创建转换。

如果不存在,则创建TranslateTransform。

然后累积里面的翻译。

此致

答案 1 :(得分:0)

尝试使用Canvas.SetTopCanvas.SetLeft

Rectangle myRectangle = new Rectangle();
myRectangle += myRectangle_MouseLeftButtonDown;

void myRectangle_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    myRectangle.MouseMove += origin_MouseMove;
}

void myRectangle_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
    Point p = new Point()
    {   
        // Just round the coordinates
        X = Math.Round(e.GetPosition(canvas).X, 0, MidpointRounding.AwayFromZero),  
        Y = Math.Round(e.GetPosition(canvas).Y, 0, MidpointRounding.AwayFromZero),
    };

    Canvas.SetTop(myRectangle, p.Y);
    Canvas.SetLeft(myRectangle, p.X);

    myRectangle.MouseLeftButtonUp += myRectangle_MouseLeftButtonUp;
}

void myRectangle_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    myRectangle.MouseMove -= origin_MouseMove;
    myRectangle.MouseLeftButtonUp -= origin_MouseLeftButtonUp;
}

答案 2 :(得分:-1)

Mvvm行为方法将参考添加到:     System.Windows.Interactivity。

  1. 在XAML中:

    <Canvas x:Name="MyCanvas" Background="#00FFFFFF">
    <i:Interaction.Behaviors>
        <!--soSandBox is the reffrence to the behavior-->
        <soSandBox:MoveElementsInCanvasBehavior/>
    </i:Interaction.Behaviors>
    <Rectangle x:Name="_MyTestRect1" Fill="Tomato" Width="50" Height="50"/>
    <Rectangle x:Name="_MyTestRect2" Fill="Tomato" Width="50" Height="50"/>
    <Rectangle x:Name="_MyTestRect3" Fill="Tomato" Width="50" Height="50"/></Canvas>
    
  2. 行为代码:

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.MouseLeftButtonDown += AssociatedObjectOnMouseLeftButtonDown;
        AssociatedObject.MouseLeftButtonUp += AssociatedObjectOnMouseLeftButtonUp;
        AssociatedObject.MouseMove += AssociatedObjectOnMouseMove;
    }
    
    private void AssociatedObjectOnMouseMove(object sender, MouseEventArgs e)
    {
        if (_shape != null && _shape.IsMouseCaptured)
        {
            _p2 = e.GetPosition(AssociatedObject);
            _shape.SetValue(Canvas.TopProperty, _p2.Y - _originalOffsetFromTop);
            _shape.SetValue(Canvas.LeftProperty, _p2.X - _originalOffsetFromLeft);
        }
    }
    
    private void AssociatedObjectOnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (_shape == null) return;
        _shape.ReleaseMouseCapture();
        _shape = null;
    }
    
    private double GetDist(double originalValue, double newValue)
    {
        if (double.IsNaN(originalValue) || double.IsInfinity(originalValue))
            return Math.Abs(newValue - 0);
        return Math.Abs(newValue - originalValue);
    }
    
    private void AssociatedObjectOnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _shape = e.OriginalSource as Shape;
        if (_shape != null)
        {
            _p1 = e.GetPosition(AssociatedObject);
            _shape.CaptureMouse();
            _originalOffsetFromTop = GetDist((double)_shape.GetValue(Canvas.TopProperty), _p1.Y);
            _originalOffsetFromLeft = GetDist((double)_shape.GetValue(Canvas.LeftProperty), _p1.X);
        }
    }
    
    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.MouseLeftButtonDown -= AssociatedObjectOnMouseLeftButtonDown;
        AssociatedObject.MouseLeftButtonUp -= AssociatedObjectOnMouseLeftButtonUp;
        AssociatedObject.MouseMove -= AssociatedObjectOnMouseMove;
    }
    
    1. 要点: 通过这种方式,您可以在画布中放置尽可能多的元素,当您单击元素时(当此元素是形状时),您将能够移动它。
  3. enter image description here

    1. 翻译变换XAML:

      <Canvas x:Name="MyCanvas" Background="#00FFFFFF">
      <i:Interaction.Behaviors>
          <!--convert event to command mechanism-->
          <soSandBox:CanvasMouseEventObservingBehavior 
              OnMouseMoveAction="{Binding OnMouseMoveAction, UpdateSourceTrigger=PropertyChanged}"
              OnMouseRightButtonDownAction="{Binding OnMouseRightButtonDownAction, UpdateSourceTrigger=PropertyChanged}"
              OnMouseRightButtonUpAction="{Binding OnMouseRightButtonUpAction, UpdateSourceTrigger=PropertyChanged}"/>
      </i:Interaction.Behaviors>
      <Rectangle x:Name="_MyTestRect1" Fill="Tomato" Width="50" Height="50">
          <Rectangle.RenderTransform>
              <TransformGroup>
                  <TranslateTransform X="{Binding TranslateTransformX, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                                      Y="{Binding TranslateTransformY, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></TranslateTransform>
              </TransformGroup>
          </Rectangle.RenderTransform>
      </Rectangle></Canvas>
      
    2. 翻译转换视图模型(翻译相关代码):

          private void RightMouseUp(Point obj)
      {
          _originalPoint = obj;
          _currentOffsetByX = GetDist(_currentOffsetByX, obj.X);
          _currentOffsetByY = GetDist(_currentOffsetByY, obj.Y);
      
      }
      
      private void RightMouseDown(Point obj)
      {
          _originalPoint = obj;
          _currentOffsetByX = GetDist(_currentOffsetByX, obj.X);
          _currentOffsetByY = GetDist(_currentOffsetByY, obj.Y);
      }
      
      private void MouseMoved(Point obj)
      {
          TranslateTransformX = obj.X - _currentOffsetByX;
          TranslateTransformY = obj.Y - _currentOffsetByY;
      }
      
      private double GetDist(double originalValue, double newValue)
      {
          if (double.IsNaN(originalValue) || double.IsInfinity(originalValue))
              return Math.Abs(newValue - 0);
          return Math.Abs(newValue - originalValue);
      }
      
      public double TranslateTransformY
      {
          get { return _translateTransformY; }
          set
          {
              _translateTransformY = value;
              OnPropertyChanged();
          }
      }
      
      public double TranslateTransformX
      {
          get { return _translateTransformX; }
          set
          {
              _translateTransformX = value;
              OnPropertyChanged();
          }
      }
      
    3. 此致