代码之家  ›  专栏  ›  技术社区  ›  Stefan

无法让简单的WPF拖放工作

  •  4
  • Stefan  · 技术社区  · 15 年前

    对于一个简单的测试,我想将一个按钮拖到一个文本框中。我可以开始拖动按钮,但不会引发放置事件。我错过了什么?

    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;
        }
    }
    
    2 回复  |  直到 15 年前
        1
  •  2
  •   Rachel    15 年前

    我认为这与当你开始拖动事件时,按钮控件捕捉鼠标输入有关。之后所做的任何鼠标移动都会注册到按钮而不是应用程序

    实际上,我也遇到了类似的问题,最终使用了mouseenter/leave事件,而不是内置的wpf拖放框架。

        2
  •  2
  •   Stefan    15 年前

    这可能是一些奇怪的情况,但要解决它,我需要处理或拖动事件,包括预览版本。

    以下是如何使其工作的方法。

    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;
        }
    }