在wpf上,我已经实现了建议作为问题答案的实践:How to drag a UserControl inside a Canvas,以便在画布上拖动和移动项目(形状,子画布)。但正如正确指出同一问题的下一个答案,方法中存在一个缺陷:
private void Control_MouseMove(object sender, MouseEventArgs e)
{
var draggableControl = sender as UserControl;
if (isDragging && draggableControl != null)
{
Point currentPosition = e.GetPosition(this.Parent as UIElement);
var transform = draggableControl.RenderTransform as TranslateTransform;
if (transform == null)
{
transform = new TranslateTransform();
draggableControl.RenderTransform = transform;
}
transform.X = currentPosition.X - clickPosition.X;
transform.Y = currentPosition.Y - clickPosition.Y;
}
}
它使用RenderTranform,它不会永久改变项目的位置,而是改变其视觉位置。结果是该项目仅在下一个鼠标事件时返回其初始位置,因此拖放操作无法正常工作(您无法以这种方式实际移动它,只能直观地移动它。)应该对它进行哪种修改纠正方法的功能?是否有类似的做法可以正确执行任务?我应该使用其他变换,如布局变换吗?
答案 0 :(得分:2)
你所做的是一种可能的实现,但在WPF中已经存在一个用于拖动的控件:Thumb。
示例:
<Canvas Width="200" Height="200" Background="Yellow">
<Thumb x:Name="DragThumb" DragDelta="Mover_DragDelta" Canvas.Top="20" Canvas.Left="10" Background="Gray" Width="50" Height="50" >
<Thumb.Template>
<ControlTemplate>
<Rectangle Fill="Black" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
后面有一个非常简单的代码:
private void Mover_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
Canvas.SetLeft(DragThumb, Canvas.GetLeft(DragThumb) + e.HorizontalChange);
Canvas.SetTop(DragThumb, Canvas.GetTop(DragThumb) + e.VerticalChange);
}
已经移动了你的画布。 (它保持Canvas.Top / Canvas.Left位置设置)。
答案 1 :(得分:1)
您可以使用Canvas.Left和Canvas.Top属性,而不是使用RenderTransform进行模拟。
Canvas.SetLeft(this, Canvas.GetLeft(this) + delta.X);
Canvas.SetTop(this, Canvas.GetTop(this) + delta.Y);