miniHessel
miniHessel

Reputation: 846

Correct way of setting an elements position in relevance to another element or pointer

What is the correct approach to set the position of a object in relevance to the pointer? I have tried

private void TextBlockPressed(object sender,   PointerRoutedEventArgs e)
{
  var currentPoint = e.GetCurrentPoint(sender as UIElement);
  Canvas.SetLeft(element, e.Position.X);
}

Upvotes: 0

Views: 79

Answers (1)

Andrew KeepCoding
Andrew KeepCoding

Reputation: 13666

Let me show you a basic example which lets you drag a Rectangle on a Canvas:

*.xaml

<Canvas
    x:Name="CanvasControl"
    Background="Transparent"
    PointerMoved="CanvasControl_PointerMoved"
    PointerPressed="CanvasControl_PointerPressed"
    PointerReleased="CanvasControl_PointerReleased">
    <Rectangle
        Width="100"
        Height="100"
        Fill="SkyBlue"
        PointerPressed="Rectangle_PointerPressed" />
</Canvas>

*.xaml.cs

private UIElement? DraggingUIElement { get; set; }

private Point DeltagStartPoint { get; set; }

private void Rectangle_PointerPressed(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
    DraggingUIElement = sender as UIElement;
}

private void CanvasControl_PointerReleased(object sender, PointerRoutedEventArgs e)
{
    DraggingUIElement = null;
}

private void CanvasControl_PointerPressed(object sender, PointerRoutedEventArgs e)
{
    if (sender is not Canvas canvasControl)
    {
        return;
    }

    DeltagStartPoint = e.GetCurrentPoint(canvasControl).Position;

}

private void CanvasControl_PointerMoved(object sender, PointerRoutedEventArgs e)
{
    if (DraggingUIElement is null ||
        sender is not Canvas canvasControl)
    {
        return;
    }

    var point = e.GetCurrentPoint(canvasControl).Position;
    double deltaX = point.X - DeltagStartPoint.X;
    double deltaY = point.Y - DeltagStartPoint.Y;

    double elemnetX = Canvas.GetLeft(DraggingUIElement);
    double elementY = Canvas.GetTop(DraggingUIElement);

    double newX = elemnetX + deltaX;
    double newY = elementY + deltaY;

    Canvas.SetLeft(DraggingUIElement, newX);
    Canvas.SetTop(DraggingUIElement, newY);

    DeltagStartPoint = point;
}

UPDATE

If you want to center the rectangle on the pointer when the rectangle is clicked:

private void Rectangle_PointerPressed(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
    if (sender is not UIElement uiElement)
    {
        return;
    }

    DraggingUIElement = uiElement;
    var positionOnDraggingUIElement = e.GetCurrentPoint(DraggingUIElement).Position;
    double draggingElementCenterX = DraggingUIElement.ActualSize.X / 2;
    double draggingElementCenterY = DraggingUIElement.ActualSize.Y / 2;

    var delta = new Point(
        draggingElementCenterX - positionOnDraggingUIElement.X,
        draggingElementCenterY - positionOnDraggingUIElement.Y);
    Canvas.SetLeft(DraggingUIElement, Canvas.GetLeft(DraggingUIElement) - delta.X);
    Canvas.SetTop(DraggingUIElement, Canvas.GetTop(DraggingUIElement) - delta.Y);
}

Upvotes: 1

Related Questions