2011-11-04 88 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);