0

给定的代码可以很好地拖放一个控件实例。如果我再次尝试删除相同的实例,则会引发异常:

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

如何在 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>
4

2 回答 2

1

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

而不是提前加载用户控件,您应该构造它们MyDesignerCanvas_Drop(即使用Activator与您现在在 中使用它相同的方式LoadUsercontrols)并将生成的控件分配给UserControl.Content.

于 2012-04-25T09:15:25.023 回答
0

我认为你必须克隆控制_userControls[((System.Windows.Controls.HeaderedItemsControl)(treeItem)).Header.ToString()]MyDesignerCanvas_Drop

于 2012-04-25T09:08:23.140 回答