Каков правильный подход к установке положения объекта относительно указателя? я пытался
private void TextBlockPressed(object sender, PointerRoutedEventArgs e)
{
var currentPoint = e.GetCurrentPoint(sender as UIElement);
Canvas.SetLeft(element, e.Position.X);
}
Трудно сказать, какой способ вы имеете в виду, пропорциональность на якоре или фиксированную дистанцию. Что касается элемента и его дочернего содержимого, см. Выравнивание, поля, отступы.
В качестве примера: допустим, вы хотите перетащить прямоугольник на холсте.
Позвольте мне показать вам простой пример, который позволяет перетащить Rectangle
на 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;
}
ОБНОВЛЯТЬ
Если вы хотите центрировать прямоугольник на указателе при щелчке по прямоугольнику:
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);
}
На самом деле это тот же самый подход, который я в конечном итоге использовал. Спасибо за ответ. Теперь хочу задать вам дополнительный вопрос: что, если вы хотите, чтобы прямоугольник располагался так, чтобы указатель находился в центре? Другими словами, когда вы перетаскиваете объект, он всегда находится по центру указателя.
Обновил свой ответ. Надеюсь, поможет.
Протестирую, спасибо!
Трудно сказать с таким небольшим количеством кода. Canvas.SetLeft (и другие SetXXX) имеют смысл и работают только в том случае, если элемент является дочерним элементом родительского элемента Canvas. В остальном все зависит от родителя.