简体   繁体   English

运行时在窗体上拖动控件

[英]Dragging Controls on Form at runtime

I've just started using WPF.我刚刚开始使用 WPF。 But I'm trying to add my code that (from Winforms) enables the user to drag any control whereever they wish at runtime.但是我正在尝试添加我的代码(来自 Winforms)使用户能够在运行时将任何控件拖动到他们想要的任何位置。 But I can't seem to get the current Location of the mouse... Eh?但我似乎无法获得鼠标的当前位置......嗯? There is no Location for Mouse?鼠标没有位置? :( :(

In the Mouse event you can use e.GetPosition to get the current mouse position.在鼠标事件中,您可以使用 e.GetPosition 来获取当前鼠标位置。 This function can provide the mouse position relative to a specific element or you can just pass null.此函数可以提供相对于特定元素的鼠标位置,或者您可以只传递 null。

Here is a very simple example, no hit testing or anything, just a button that you can drag around.这是一个非常简单的例子,没有命中测试或任何东西,只是一个可以拖动的按钮。 And I used a canvas to keep it short, but you would probably do better to use a transform and translate the control to the desired position.我使用了画布来保持简短,但您可能会更好地使用转换并将控件转换到所需的位置。

<Window x:Class="WpfApplication1.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 PreviewMouseLeftButtonDown="Canvas_PreviewMouseLeftButtonDown" 
            PreviewMouseMove="Canvas_PreviewMouseMove" 
            PreviewMouseLeftButtonUp="Canvas_PreviewMouseLeftButtonUp">
        <Button Name="dragButton" Width="80" Height="21" Canvas.Left="50" Canvas.Top="10">Drag Me!</Button>
    </Canvas>
</Window>


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

namespace WpfApplication1
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();      
    }    

    private Point _startPoint;
    private bool _dragging = false;

    private void Canvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {         
      if (dragButton.CaptureMouse())
      {        
        _startPoint = e.GetPosition(null);
        _dragging = true;        
      }
    }

    private void Canvas_PreviewMouseMove(object sender, MouseEventArgs e)
    {
      if (_dragging)
      {        
        Point newPoint = e.GetPosition(null);
        double dx = newPoint.X - _startPoint.X;
        double dy = newPoint.Y - _startPoint.Y;

        Canvas.SetLeft(dragButton, Canvas.GetLeft(dragButton) + dx);
        Canvas.SetTop(dragButton, Canvas.GetTop(dragButton) + dy);
        _startPoint = newPoint;
      }
    }

    private void Canvas_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
      if (_dragging)
      {        
        _dragging = false;
        dragButton.ReleaseMouseCapture();
      }
    }    
  }
}

I think the way to get this information in WPF is to use some attached events.我认为在 WPF 中获取此信息的方法是使用一些附加事件。 You can get into the event handlers for PreviewMouseDown, PreviewMouseMove and PreviewMouseUp to get information about the mouse when it is over certain controls and the user is pressing/releasing a mouse button, moving the mouse, etc.您可以进入 PreviewMouseDown、PreviewMouseMove 和 PreviewMouseUp 的事件处理程序,以在鼠标位于某些控件上方并且用户按下/释放鼠标按钮、移动鼠标​​等时获取有关鼠标的信息。

There is a good practical example of this here: Generic WPF Drag-and-Drop Adorner这里有一个很好的实际例子: Generic WPF Drag-and-Drop Adorner

I don't know why it's not correct, but it's working for me.我不知道为什么它不正确,但它对我有用。

private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    moving = true;
}

private void Button_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    moving = false;
}

private void Button_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (moving)
    {
        Canvas.SetTop(this, e.GetPosition(Parent as Canvas).Y);
        Canvas.SetLeft(this, e.GetPosition(Parent as Canvas).X);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM