我正在尝试制作一个 C# WPF 表单,可以通过点击并用鼠标拖动它来移动屏幕。该窗体的特点是完全透明且只包含一个图像。这意味着窗口样式为无,不显示在任务栏中。因此,在应用程序运行时,你只能看到一个小图像 - 理想情况下,我希望能够通过按住鼠标左键并将其移动来拖动它到桌面上任何位置。
请问是否有简单的方法可以实现这一点,或者我是否忽略了内置的功能?
谢谢。
请问是否有简单的方法可以实现这一点,或者我是否忽略了内置的功能?
谢谢。
之前的回答已经接近正确答案,但完整的示例代码如下:
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
DragMove();
}
}
您可以在窗口的鼠标按下事件中使用Window.DragMove方法。
private bool _IsDragInProgress { get; set; }
private System.Windows.Point _FormMousePosition {get;set;}
代码:
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
this._IsDragInProgress = true;
this.CaptureMouse();
this._FormMousePosition = e.GetPosition((UIElement)this);
base.OnMouseLeftButtonDown(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (!this._IsDragInProgress)
return;
System.Drawing.Point screenPos = (System.Drawing.Point)System.Windows.Forms.Cursor.Position;
double top = (double)screenPos.Y - (double)this._FormMousePosition.Y;
double left = (double)screenPos.X - (double)this._FormMousePosition.X;
this.SetValue(MainWindow.TopProperty, top);
this.SetValue(MainWindow.LeftProperty, left);
base.OnMouseMove(e);
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
this._IsDragInProgress = false;
this.ReleaseMouseCapture();
base.OnMouseLeftButtonUp(e);
}
e.GetPosition
和 System.Windows.Forms.Cursor.Position
,您需要将 System.Windows.Forms.Cursor.Position
转换为 Point
。它看起来像这样:this._FormMousePosition = new Point(System.Windows.Forms.Cursor.Position.X, System.Windows.Forms.Cursor.Position.Y);
这个方法可以工作,但是 WPF 表单在初始点击时会跳跃。this._FormMousePosition = e.GetPosition((UIElement)this);
不会导致表单跳跃。 - Agrejuspublic partial class MainWindow : Window
{
private WindowsDragger _dragger;
public MainWindow()
{
InitializeComponent();
_dragger = new WindowsDragger(this);
}
}
帮助类:
class WindowsDragger
{
private readonly Window _window;
private Point _dragDelta;
public WindowsDragger(Window window)
{
_window = window;
_window.MouseLeftButtonDown += MouseLeftButtonDown;
_window.MouseLeftButtonUp += MouseLeftButtonUp;
_window.MouseMove += MouseMove;
}
void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_dragDelta = e.GetPosition(_window);
Mouse.Capture(_window);
}
void MouseMove(object sender, MouseEventArgs e)
{
if (Equals(_window, Mouse.Captured))
{
var pos = _window.PointToScreen(e.GetPosition(_window));
var verifiedPos = CoerceWindowBound(pos - _dragDelta);
_window.Left = verifiedPos.X;
_window.Top = verifiedPos.Y;
}
}
void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (Equals(_window, Mouse.Captured))
Mouse.Capture(null);
}
private Vector CoerceWindowBound(Vector newPoint)
{
// Snap to the current desktop border
var screen = WpfScreen.GetScreenFrom(_window);
var wa = screen.WorkingArea;
if (newPoint.X < wa.Top) newPoint.X = wa.Top;
if (newPoint.Y < wa.Left) newPoint.Y = wa.Left;
if (_window.Width + newPoint.X > wa.Right) newPoint.X = wa.Right - _window.Width;
if (_window.Height + newPoint.Y > wa.Bottom) newPoint.Y = wa.Bottom - _window.Height;
return newPoint;
}
}
其中 WpfScreen 是从这里获取的:如何在 WPF 中获取当前屏幕的大小?
this.MouseDown += delegate{DragMove();};
}`