在WPF中拖放多个用户控件实例

时间:2012-04-25 09:06:22

标签: wpf

通过拖放一个控件实例,给定的代码可以正常工作。如果我再次尝试删除相同的实例,则抛出异常:

  

指定的元素已经是另一个元素的逻辑子元素。首先断开它。

如何在Canvas上删除多个用户控件实例,类似于Visual Studio工具箱的工作方式?

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>

2 个答案:

答案 0 :(得分:1)

您无法将相同的控件添加到不同的容器中 - 控件只能在可视树中出现一次。

您应该预先加载用户控件,而不是MyDesignerCanvas_Drop构建它们(即使用Activator,就像您现在在LoadUsercontrols中使用它一样)并分配得到对UserControl.Content的控制权。

答案 1 :(得分:0)

我认为您必须在_userControls[((System.Windows.Controls.HeaderedItemsControl)(treeItem)).Header.ToString()]

中克隆控件MyDesignerCanvas_Drop