2010-11-22 91 views
4

對於一個簡單的測試,我想將一個按鈕拖到一個文本框。我可以開始拖動按鈕,但不會引發Drop事件。我錯過了什麼?不能簡單的WPF拖放工作

的XAML:

<Window x:Class="DayPlanner.View.DnDTest" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="DnDTest" Height="200" Width="200"> 
    <StackPanel> 
     <Button Name="button" 
       Content="OK" 
       PreviewMouseLeftButtonDown="button_PreviewMouseLeftButtonDown" 
       PreviewMouseMove="button_PreviewMouseMove"/> 
     <TextBox Name="textBox" 
       AllowDrop="True" 
       DragEnter="textBox_DragEnter" 
       Drop="textBox_Drop"/> 
    </StackPanel> 
</Window> 

代碼:

public partial class DnDTest : Window 
{ 
    public DnDTest() 
    { 
     InitializeComponent(); 
    } 

    private Point dragStartPoint; 

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

    private static bool IsDragging(Point dragStartPoint, MouseEventArgs e) 
    { 
     var diff = e.GetPosition(null) - dragStartPoint; 
     return 
      e.LeftButton == MouseButtonState.Pressed && 
      (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || 
       Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance); 
    } 

    private void button_PreviewMouseMove(object sender, MouseEventArgs e) 
    { 
     if (IsDragging(dragStartPoint, e)) 
     { 
      DragDrop.DoDragDrop(button, new DataObject("Button", button), DragDropEffects.Move); 
      e.Handled = true; 
     } 
    } 

    private void textBox_DragEnter(object sender, DragEventArgs e) 
    { 
     e.Handled = true; 
    } 

    private void textBox_Drop(object sender, DragEventArgs e) 
    { 
     var button = (Button)e.Data.GetData("Button"); 
     textBox.Text = string.Format("[0]", button.Content.ToString()); 
     e.Handled = true; 
    } 
} 
+0

您沒有設置拖拽效應。像e.Effects = DragDropEffects.Copy;在你的DragEnter處理程序將工作。 – genus 2013-02-28 23:07:59

回答

2

這可能是一些奇怪的情況,但要解決它,我需要處理或拖動事件,包括預覽版本。

以下是如何使其工作。

的XAML:

<Window x:Class="DayPlanner.View.DnDTestBasic" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="DnDTestBasic" Height="200" Width="200"> 
    <StackPanel> 
     <Button Name="button" 
       Content="OK" 
       PreviewMouseLeftButtonDown="button_PreviewMouseLeftButtonDown" 
       PreviewMouseMove="button_PreviewMouseMove"/> 
     <TextBox Name="textBox" 
       AllowDrop="True" 
       PreviewDragEnter="textBox_Dragging" 
       DragEnter="textBox_Dragging" 
       PreviewDragOver="textBox_Dragging" 
       DragOver="textBox_Dragging" 
       Drop="textBox_Drop"/> 
     <TextBlock Name="status" 
        Text="No dragging"/> 
    </StackPanel> 
</Window> 

代碼:

public partial class DnDTestBasic : Window 
{ 
    public DnDTestBasic() 
    { 
     InitializeComponent(); 
    } 

    private Point dragStartPoint; 

    private void button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     dragStartPoint = e.GetPosition(null); 
     status.Text = "New drag start position"; 
    } 

    private static bool IsDragging(Point dragStartPoint, MouseEventArgs e) 
    { 
     var diff = e.GetPosition(null) - dragStartPoint; 
     return 
      e.LeftButton == MouseButtonState.Pressed && 
      (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || 
      Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance); 
    } 

    private void button_PreviewMouseMove(object sender, MouseEventArgs e) 
    { 
     if (IsDragging(dragStartPoint, e)) 
     { 
      status.Text = "Starting drag..."; 
      DragDrop.DoDragDrop(button, new DataObject("Button", button), DragDropEffects.Copy); 
      status.Text = "Dragging done."; 
      e.Handled = true; 
     } 
    } 

    private void textBox_Dragging(object sender, DragEventArgs e) 
    { 
     if (e.Data.GetDataPresent("Button")) 
      e.Effects = DragDropEffects.Copy; 
     else 
      e.Effects = DragDropEffects.None; 
     e.Handled = true; 
    } 

    private void textBox_Drop(object sender, DragEventArgs e) 
    { 
     var button = (Button)e.Data.GetData("Button"); 
     textBox.Text = string.Format("[{0}]", button.Content.ToString()); 
     e.Handled = true; 
    } 
} 
2

我相信這是與事實,當你開始拖動事件,按鈕控制捕獲鼠標輸入的事情。後註冊到該按鈕,而不是到應用

你做任何的鼠標動作其實我也有類似的問題,並最終使用的MouseEnter/Leave事件,而不是建立在WPF拖/放框架。

+0

嗨,我有類似的情況是否有任何參考我可以看看。 – Eldho 2014-07-22 05:52:03

+0

@Eldho [This answer](http://stackoverflow.com/a/2639399/302677)在SO上幫助我走了很多正確的方向 – Rachel 2014-07-22 11:18:18