2011-11-04 56 views
0

在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

控件的位置被重置的事实与RenderTransform的使用无关,如果有的话只是不好的编码。 –

+0

查看http://msdn.microsoft.com/en-us/library/system.windows.uielement.rendertransform.aspx中的备注。它讲述的是一种“暂时效应”。 – arjacsoh

+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 Positions被设置)。

+0

好吧,虽然可以在拇指上添加更多形状以构建复合形状吗?或者我应该在其中包装一张儿童画布并将这些形状放在儿童画布上? – arjacsoh

+0

当然,您可以根据需要在Thumb中添加任何内容。您可以更新ControlTemplate并添加任何你想要的。 – fixagon

1

你可以使用Canvas.Left和Canvas.Top属性来代替RenderTransform。

Canvas.SetLeft(this, Canvas.GetLeft(this) + delta.X); 
Canvas.SetTop(this, Canvas.GetTop(this) + delta.Y);