Dragging Controls on Form at runtime
I've just started using WPF. But I'm trying to add my code that (from Winforms) enables the user to drag any control whereever they wish at 开发者_如何学Goruntime. 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. This function can provide the mouse position relative to a specific element or you can just pass 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. 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.
There is a good practical example of this here: 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);
}
}
精彩评论