简体   繁体   English

WPF:如何translateTransform 一个矩形?

[英]WPF: How to translateTransform a rectangle?

I'm trying to move a rectangle drawn in Canvas by mouse (drag and drop).我正在尝试通过鼠标(拖放)移动在 Canvas 中绘制的矩形。

When I click on the Rectangle and move the mouse (keep clicking) to a new position it's OK:当我单击矩形并将鼠标(继续单击)移动到新位置时,就可以了:

在此处输入图片说明

But when I click on it again and move the mouse just a bit the Rectangle move to old position:但是当我再次单击它并稍微移动鼠标时,矩形移动到旧位置:

在此处输入图片说明

I don't know why it is.我不知道为什么会这样。 Can anybody give me some explaination?有人可以给我一些解释吗?

Here is my code (all parameters have been assigned and initialized).这是我的代码(所有参数都已分配和初始化)。 Thanks in advance!提前致谢!

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

        }

You should not create the transform every time otherwise you reset the translation.您不应每次都创建转换,否则会重置翻译。

Create a TranslateTransform if none exist.如果不存在,则创建一个 TranslateTransform。

Then cumulate the translations inside.然后在里面累积翻译。

Regards问候

Try just using the Canvas.SetTop and Canvas.SetLeft .尝试只使用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;
}

Mvvm Behavior Approach add the refference to: System.Windows.Interactivity. Mvvm Behavior Approach 添加对:System.Windows.Interactivity 的引用。

  1. In XAML:在 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. Behavior code:行为代码:

     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. Summary: This way you can put inside the canvas as much elements as you wish, and when you click the element (and when this element is a shape) you will be able to move it.总结:通过这种方式,您可以在画布中放入任意数量的元素,并且当您单击该元素时(当该元素是一个形状时),您将能够移动它。

在此处输入图片说明

  1. Translate Transform XAML:转换转换 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. Translate Transform view model (translation related code): Translate Transform 视图模型(翻译相关代码):

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

Regards问候

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM