Кнопка перетаскивания в том же приложении вызывает исключение - PullRequest
0 голосов
/ 17 февраля 2012

У меня есть холст, содержащий кнопку, которую я хочу перетаскивать на другой холст. Я хочу скопировать кнопку на другой холст. Вот код, который я использую:

XAML:

<Window>
    <Grid>
        <Canvas
            Height="300"
            Width="500"
            Background="Gray">
            <Canvas
                Name="cnvToolBox"
                Canvas.Left="10"
                Canvas.Top="10"
                Background="AliceBlue"
                Width="100"
                Height="200">
                <Button
                    Content="Drag Me!"
                    PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown"
                    PreviewMouseMove="Button_PreviewMouseMove"></Button>
            </Canvas>
            <Rectangle 
                Canvas.Left="119"
                Canvas.Top="9"
                Width="102"
                Height="202"
                StrokeDashArray="0.5 1.0 0.3" 
                Stroke="Black" 
                StrokeThickness="2"/>
            <Canvas    
                Name="cnvButtonDropZone"
                Canvas.Left="120"
                Canvas.Top="10"
                Width="100"
                Height="200"
                Background="LightGreen"
                AllowDrop="True"
                DragEnter="Canvas_DragEnter"
                Drop="Canvas_Drop">
            </Canvas>
        </Canvas>
    </Grid> 
</Window>

Вот код позади:

public partial class MainWindow : Window
{
    private Point startPoint;

    public MainWindow()
    {
        InitializeComponent();
    }

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

    private void Button_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        Point currentPosition = e.GetPosition(null);
        Vector diff = startPoint - currentPosition;

        if (e.LeftButton == MouseButtonState.Pressed &&
            (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
            Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
        {
            Button button = sender as Button;

            DataObject dragData = new DataObject("myFormat", button);
            DragDrop.DoDragDrop(button, dragData, DragDropEffects.Copy);
        }
    }

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

    private void Canvas_Drop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent("myFormat"))
        {
            Button button = e.Data.GetData("myFormat") as Button;

            Canvas canvas = sender as Canvas;
            canvas.Children.Add(button);

        }
    }
}

Когда я опускаю кнопку, я получаю следующее исключение при добавлении кнопки на холст:

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

Я просто пытаюсь научиться перетаскивать элементы управления и не совсем понимаю, что означает эта ошибка и как ее устранить. Я не знаю, где я иду не так. Любые предложения приветствуются.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 17 февраля 2012

Кнопка принадлежит ее родительскому cnvToolBox.Вы должны удалить его из cnvToolBox перед добавлением его на холст.

            cnvToolBox.Children.Remove(button);
            var canvas = sender as Canvas;
            canvas.Children.Add(button);

Это переместит кнопку с панели инструментов на холст.Если вы действительно хотите клонировать элемент, вы хотите что-то вроде:

        if (e.Data.GetDataPresent("myFormat"))
        {
            var contentControl = (ContentControl)e.Data.GetData("myFormat");

            var constructorInfo = contentControl.GetType().GetConstructor(new Type[] {});
            if (constructorInfo != null)
            {
                var newElement = (UIElement)constructorInfo.Invoke(new object[]{});

                var newContentControl = newElement as ContentControl;
                if(newContentControl != null)
                {
                    newContentControl.Content = contentControl.Content;
                }

                ((Panel)sender).Children.Add(newElement);
            }
        }
1 голос
/ 17 февраля 2012

Это потому, что у Button уже есть родитель, связанный с ним; предыдущий Canvas.

Вы можете установить родительский элемент для кнопки в нуль; что по существу удалит его из логических отношений.

button.Parent = null;

После этого вы сможете добавить эту кнопку к другой Canvas, как вы сделали в своем коде позади.

Вы также можете удалить Button из свойства Children напрямую, если хотите, и затем добавить его соответствующим образом в новый Canvas.

Canvas.Children.Remove(button);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...