拖动

时间:2015-12-02 16:02:22

标签: wpf drag-and-drop position mouse drag

我希望在拖动鼠标时移动鼠标位置。

这是我最小的不工作的例子:

MainWindow.xaml:

<Window x:Class="WpfApplication8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Canvas x:Name="_canvas" Background="Green">
        <TextBlock x:Name="_positionTextBlock"/>
        <Rectangle x:Name="_dragSource"
                   Width="20"
                   Height="50"
                   Fill="Blue" 
                   Canvas.Top="150" 
                   Canvas.Left="20" 
                   PreviewMouseDown="DoDrag"/>
        <Rectangle x:Name="_dragTarget"
                   Width="60" 
                   Height="70"
                   Fill="Red" 
                   Canvas.Top="110" 
                   Canvas.Left="300" 
                   AllowDrop="True"/>
    </Canvas>
</Window>

MainWindow.xaml.cs:

using System.Windows;
using System.Windows.Input;

namespace WpfApplication8
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void DoDrag(object sender, MouseButtonEventArgs e)
        {
            DragDrop.DoDragDrop(_dragSource, "abc", DragDropEffects.Move);
        }
    }
}

正如您所看到的:我有一个名为TextBlock的{​​{1}},它应该在拖动时显示当前鼠标位置。

编辑(长篇故事):我有一个绿色矩形,可以在红色矩形上拖动和下垂。我的要求是,在拖动绿色矩形时显示鼠标位置。

我该怎么做?

我尝试过:

_positionTextBlock的构造函数更改为:

MainWindow

但这仅显示鼠标悬停在红色矩形上的位置。

我也尝试过:

public MainWindow()
{
    InitializeComponent();
    DragOver += (s, e) => _positionTextBlock.Text = e.GetPosition(_canvas).ToString();
}

public MainWindow() { InitializeComponent(); MouseMove += (s, e) => _positionTextBlock.Text = e.GetPosition(_canvas).ToString(); } - 在拖动时不会触发事件

我也尝试过:

MouseMove

但这似乎得到了屏幕坐标中的窗口位置。

这就是我被卡住的地方。有没有人有任何想法?

2 个答案:

答案 0 :(得分:0)

使用PreviewMouseMove

进行编辑

第二次修改:完整示例

XAML:

<Canvas x:Name="_canvas" Background="Green">
    <TextBlock x:Name="_positionTextBlock"/>
    <Rectangle x:Name="_dragSource"
               Width="20"
               Height="50"
               Fill="Blue" 
               Canvas.Top="150" 
               Canvas.Left="20" 
               PreviewMouseMove="DragSourcePreviewMouseMove"/>
    <Rectangle x:Name="_dragTarget"
               Width="60" 
               Height="70"
               Fill="Red" 
               Canvas.Top="110" 
               Canvas.Left="300" 
               AllowDrop="True"/>
</Canvas>

代码隐藏:

public MainWindow()
{
    InitializeComponent();
}

private void DragSourcePreviewMouseMove(object sender, MouseEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed)
    {
        _positionTextBlock.Text = e.GetPosition(_canvas).ToString();
    }
    e.Handled = true;
}

希望这有帮助。

答案 1 :(得分:0)

我尝试了您的演示,发现如果您在窗口上设置 AllowDrop="True",则 DragOver 事件有效。

如果不想掉到窗口,可以监听窗口的PreviewDragOver事件。然后将 DragEventArgs.Effect 设置为 None 并将 DragEventArgs.Handled 设置为 True。

您还可以通过另一种方式获取鼠标位置,该方式一直有效,但您需要一个定时器来定期刷新位置。

Visual.PointFromScreen(MousePositionToScreen);

public Point MousePositionToScreen
{
    get
    {
        GetCursorPos(out POINT p);
        return new Point(p.X, p.Y);
    }
}

[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
    public int X;
    public int Y;

    public POINT(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }
}

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool GetCursorPos(out POINT pt);

最后,您可以尝试Keith Stein's solution。它要复杂得多。