2011-12-17 7 views
1

私はItemControlをItemTemplateとして表示するItemsControlを持っています。 Canvas ItemsPanelがあります。Silverlight:CanvasのItemsControlでアイテムを移動する方法

私は

MyControlとは行動を持つマウスドラッグでキャンバス上のコントロールを移動したい

<ItemsControl ItemsSource="{Binding Path=MyItems}" Margin="200,20,0,0"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <local:MyControl Margin="10,10,10,10"/> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Canvas Height="2000" Width="2000"/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
    </ItemsControl> 

<UserControl x:Class="MyControl"> 

    <StackPanel x:Name="LayoutRoot" > 
     <Grid Background="LightBlue" Height="20"> 
    </StackPanel> 
<Interactivity:Interaction.Behaviors> 
    <Behavior:DragControlBehavior /> 
</Interactivity:Interaction.Behaviors> 
</UserControl> 

DragControlBehaviorが制御

以上のMouseMoveのキャンバス添付プロパティを設定します[更新] - ここには動作の完全なソースコードがあります

私はそれが動作キャンバスに別々にMyControlとのインスタンスを使用しますが、MyControlsのコレクションはItemsControlにである場合には、彼らはWPFでのMouseMove

に移動しない場合は、私がItemContainerStyleを使用する

public class DragControlBehavior : Behavior<MyControl> 
{ 
    private DependencyObject _parent; 
    private bool _isMouseCaptured = false; 

    protected override void OnAttached() 
    { 
     AssociatedObject.MouseLeftButtonDown += (sender, e) => 
     { 
      _isMouseCaptured = true; 
     }; 

     AssociatedObject.MouseLeftButtonUp += (sender, e) => 
     { 
      _isMouseCaptured = false; 
     }; 

     AssociatedObject.MouseMove += (sender, e) => 
     { 
      if (_isMouseCaptured) 
      { 
       if (_parent == null) 
       { 
        _parent = VisualTreeHelper.GetParent(AssociatedObject); 
        while (_parent.GetType() != typeof(Canvas)) 
         _parent = VisualTreeHelper.GetParent(_parent); 
       } 
       var pointOnCanvas = e.GetPosition((Canvas)_parent); 
       Canvas.SetTop(AssociatedObject, pointOnCanvas.Y); 
       Canvas.SetLeft(AssociatedObject, pointOnCanvas.X); 
      } 
     }; 
    } 

が、SLでそれは使用できません。

 <ItemsControl.ItemContainerStyle> 
      <Style TargetType="ContentPresenter"> 
       <Setter Property="Canvas.Left" Value="{Binding Left}"/> 
       <Setter Property="Canvas.Top" Value="{Binding Top}"/> 
      </Style> 
     </ItemsControl.ItemContainerStyle> 
+0

'DragControlBehavior'クラスの完全なソースコードを表示できますか?それがなければ、私たちはあなたの問題を再現することは困難です。 –

+0

振る舞いの完全なソースコードは –

答えて

1

あなたがItemsControlを使用する場合は、生成された各項目はContentPresenterに包まれています。ビジュアルツリーは、ビット以下のようになります。

 
System.Windows.Controls.ItemsControl 
    System.Windows.Controls.ItemsPresenter 
    System.Windows.Controls.Canvas 
     System.Windows.Controls.ContentPresenter 
     DragControlBehaviorTest.MyControl 
      ... 

DragControlBehaviorTestは、私が出て、あなたのコードを試して作成したプロジェクトの名前です。)

Canvas.LeftCanvas.Top添付プロパティを唯一の直接の子に取り組みますCanvasMyControlCanvasに直接配置すると、MyControlCanvasの子であるため、Canvas.LeftCanvas.Topを設定すると機能します。ただし、MyControlを生成するためにItemsControlを使用している場合は、とMyControlの間にContentPresenterがあります。代わりにContentPresentersCanvas.LeftCanvas.Topのプロパティを設定する必要があります。

AssociatedObjectのビジュアルツリーの上にループがあり、祖先Canvasが見つかります。これを変更して、キャンバスの直下の子を見つけることができます。

  _immediateChild = AssociatedObject; 
      _parent = VisualTreeHelper.GetParent(AssociatedObject); 
      while (_parent.GetType() != typeof(Canvas)) 
      { 
       _immediateChild = _parent; 
       _parent = VisualTreeHelper.GetParent(_parent); 
      } 
+0

ありがとうルーク。それは助けになった –

関連する問題