2012-04-25 2 views
0

Данный код отлично работает с перетаскиванием одного экземпляра элемента управления. Если я попытаюсь снова удалить тот же экземпляр, он выдает исключение:Перетаскивание нескольких экземпляров элементов управления пользователя в WPF

Указанный элемент уже является логическим дочерним элементом другого элемента. Сначала отключите его.

Как удалить несколько экземпляров элементов управления пользователя на моем холсте, как это делает Visual Studio Toolbox?

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); 
     } 
    } 
} 

В XAML Код:

<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

Вы не можете добавить такое же управление различными контейнерами - это управление может появиться только один раз в визуальном дереве.

Вместо загрузки пользовательских элементов управления заранее, вы должны строить их на MyDesignerCanvas_Drop (т.е. использовать Activator таким же образом вы используете его прямо сейчас в LoadUsercontrols) и присвоить полученный контроль в UserControl.Content.

+0

На самом деле, я использую объект управления пользователя в событии TreeViewItem_PreviewMouseMove, поэтому я загружаю его с помощью управления раньше. Если возможно, пришлите мне часть кода, чтобы сделать это. – Sunil

+0

Вы не можете загрузить элементы управления раньше, если вам нужны несколько экземпляров. –

+0

Спасибо, что обратились за помощью. – Sunil

0

Я думаю, вы должны клонировать контроль _userControls[((System.Windows.Controls.HeaderedItemsControl)(treeItem)).Header.ToString()] в MyDesignerCanvas_Drop

+0

Пожалуйста, дайте мне знать, как создать клон для _userControls. – Sunil

Смежные вопросы