2012-02-17 55 views
0

我有一個Canvas,其中包含一個我希望能夠拖放到另一個畫布中的按鈕。我想將按鈕複製到其他畫布。這裏是我使用的代碼:在同一應用程序中拖放按鈕引發異常

的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

該按鈕由其父級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); 
      } 
     } 
+0

我將畫布(這是一個面板)更改爲StackPanel,所以我可以添加多個項目。 – Phil 2012-02-17 19:16:34

+2

另外我不會像'按鈕按鈕=發件人作爲按鈕'的聲明,除非你之後立即測試null。如果你知道它必須是一個Button將它轉換爲Button。 – Phil 2012-02-17 19:24:00

+0

工作!乾杯! – 2012-02-17 20:24:54

1

這是因爲Button已經有與之相關聯的父母;之前的Canvas

您可以將Button的父項設置爲null;這將從根本上消除邏輯關係。

button.Parent = null; 

然後,您將能夠將該按鈕添加到另一個Canvas,你在你的代碼所做的後面。

如果您願意,也可以直接從Children屬性中刪除Button,然後將其相應地添加到新的Canvas中。

Canvas.Children.Remove(button);