2012-04-25 28 views
0

与えられたコードは、コントロールの1つのインスタンスをドラッグアンドドロップすると問題なく動作します。同じインスタンスをもう一度削除しようとすると、例外がスローされます。WPFのユーザーコントロールの複数のインスタンスをドラッグアンドドロップ

指定された要素はすでに別の要素の論理的な子です。最初に切断します。

Visual Studioツールボックスと同様に、キャンバスに複数のユーザーコントロールをドロップするにはどうすればよいですか? XAMLコードで

public MainWindow() 
{ 
    InitializeComponent(); 
    LoadUsercontrols(); 
} 

private void LoadUsercontrols() 
{ 
    List<string> userControlKeys = new List<string>(); 
    userControlKeys.Add("testCtrl1"); 
    userControlKeys.Add("testCtrl2"); 

    Type type = this.GetType(); 
    Assembly assembly = type.Assembly; 
    foreach (string userControlKey in userControlKeys) 
    { 
     userControlFullName = String.Format("{0}.TestControls.{1}", type.Namespace, userControlKey); 
     UserControl userControl = new UserControl(); 
     userControl = (UserControl)assembly.CreateInstance(userControlFullName); 
     _userControls.Add(userControlKey, userControl); 
    } 
} 

private void TreeViewItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    startPoint = e.GetPosition(null); 
} 

private void TreeViewItem_PreviewMouseMove(object sender, MouseEventArgs e) 
{ 
    // Get the current mouse position 
    System.Windows.Point mousePos = e.GetPosition(null); 
    Vector diff = startPoint - mousePos; 

    if (e.LeftButton == MouseButtonState.Pressed && 
    Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance && 
    Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) 
    { 
     TreeView treeView = sender as TreeView; 
     TreeViewItem treeViewItem = FindAnchestor<TreeViewItem>((DependencyObject)e.OriginalSource); 

     if (treeViewItem != null) 
     { 
      Type type = this.GetType(); 
      Assembly assembly = type.Assembly; 
      DataObject dragData = new DataObject("myFormat", _userControls[((System.Windows.Controls.HeaderedItemsControl)(treeViewItem)).Header.ToString()]); 
      DragDrop.DoDragDrop(treeViewItem, dragData, DragDropEffects.Copy); 
     } 
    } 
} 

private static T FindAnchestor<T>(DependencyObject current) where T : DependencyObject 
{ 
    do 
    { 
     if (current is T) 
     { 
      return (T)current; 
     } 
     current = VisualTreeHelper.GetParent(current); 
    } 
    while (current != null); 
    return null; 
} 

private void MyDesignerCanvas_DragEnter(object sender, DragEventArgs e) 
{ 
    if (!e.Data.GetDataPresent("myFormat") || sender == e.Source) 
    { 
     e.Effects = DragDropEffects.None; 
    } 
} 

private void MyDesignerCanvas_Drop(object sender, DragEventArgs e) 
{ 
    if (e.Data.GetDataPresent("myFormat")) 
    { 
     if (treeItem != null) 
     { 
      UserControl myCanvasItem = e.Data.GetData("myFormat") as UserControl; 
      UserControl newCanvastItem = new UserControl 
      { 
       Content = _userControls[((System.Windows.Controls.HeaderedItemsControl)(treeItem)).Header.ToString()] 
      }; 
      Point position = e.GetPosition(MyDesignerCanvas); 
      DesignerCanvas.SetLeft(newCanvastItem, position.X); 
      DesignerCanvas.SetTop(newCanvastItem, position.Y); 
      DesignerCanvas.SetZIndex(newCanvastItem, 1); 
      MyDesignerCanvas.Children.Add(newCanvastItem); 
     } 
    } 
} 

<TreeView x:Name="presetTreeView4" Grid.Row="1" > 
    <TreeViewItem Header="testCtrl1" Selected="TreeViewItem_Selected" PreviewMouseLeftButtonDown="TreeViewItem_PreviewMouseLeftButtonDown" PreviewMouseMove="TreeViewItem_PreviewMouseMove"/> 
    <TreeViewItem Header="testCtrl2" Selected="TreeViewItem_Selected" PreviewMouseLeftButtonDown="TreeViewItem_PreviewMouseLeftButtonDown" PreviewMouseMove="TreeViewItem_PreviewMouseMove"/> 
</TreeView> 
<s:DesignerCanvas x:Name="MyDesignerCanvas" AllowDrop="True" Drop="MyDesignerCanvas_Drop" DragEnter="MyDesignerCanvas_DragEnter" Background="#A6B0D2F5" DockPanel.Dock="Bottom" Margin="0" > 
</s:DesignerCanvas> 

答えて

1

に制御_userControls[((System.Windows.Controls.HeaderedItemsControl)(treeItem)).Header.ToString()]のクローンを作成するために持っていると思う - コントロールは一度だけ表示されます視覚的な木の中で。

代わりに、事前にユーザーコントロールをロードするには、MyDesignerCanvas_Dropでそれらを構築する(すなわち、ActivatorあなたがLoadUsercontrolsで、今それを使っているのと同じ方法を使用)し、UserControl.Contentへの結果のコントロールを割り当てる必要があります。

+0

実際には、私は "TreeViewItem_PreviewMouseMove"イベントでユーザーコントロールオブジェクトを使用しています。可能であれば、これを行うためのコードの一部を私に送ってください。 – Sunil

+0

複数のインスタンスが必要な場合は、コントロールを早期に読み込むことはできません。 –

+0

ご協力ありがとうございます。 – Sunil

0

は、私はあなたが別のコンテナに同じコントロールを追加することはできませんMyDesignerCanvas_Drop

+0

私は_userControlsのクローンを作成する方法を教えてください – Sunil

関連する問題