2009-05-15 6 views
14

Ich versuche, ein C# WPF-Formular zu machen, wo ich es über den Bildschirm ziehen kann, indem Sie darauf klicken und mit der Maus bewegen. Zu den Merkmalen der Formulare gehört, dass sie vollständig transparent sind und nur ein Bild enthalten. In diesem Fall ist der Fensterstil leer und wird nicht in der Taskleiste angezeigt. Im Grunde ist alles, was Sie sehen können, wenn die App läuft, ein kleines Bild - und im Idealfall möchte ich in der Lage sein, es über den Desktop zu ziehen, wenn ich mit der linken Maustaste klicke und die Maustaste gedrückt halte.Ziehen Sie ein WPF-Formular um den Desktop

Kennt jemand eine einfache Möglichkeit, die ich erreichen kann oder habe ich eine eingebaute Funktion übersehen?

Danke.

+0

Vielen Dank, ich habe nur 2 Tage für eine solche Antwort gesucht :) –

Antwort

18

Sie können die Window.DragMove-Methode im Ereignis "Mouse Down" des Fensters verwenden.

+0

Könntest du mir ein Beispiel dafür geben, wie ich das machen könnte? – Grant

+0

Es gibt ein Codebeispiel in der Dokumentation für die DragMove-Methode, das genau zeigt, was Sie tun möchten, aber es ist buchstäblich 3 Zeilen lang - behandeln Sie das MouseLeftButtonDown-Ereignis des Fensters, rufen Sie die DragMove-Methode für das Fenster auf. – Josh

20

Vorherige Antworten treffen auf die Antwort, aber die volle Beispiel ist dies:

private void Window_MouseDown(object sender, MouseButtonEventArgs e) 
    { 
     if (e.LeftButton == MouseButtonState.Pressed) 
     { 
      DragMove(); 
     } 
    } 
+3

Verwenden Sie einfach MouseLeftButtonDown und keine Überprüfung erforderlich ist –

1

Wenn Sie, wie ich, ein bisschen mehr Kontrolle über die DoDragMove() haben wollen - sagt, haben die Fenster bleiben immer im Rand des aktuellen Desktops, das habe ich gemacht.

Verbrauch:

public partial class MainWindow : Window 
{ 
    private WindowsDragger _dragger; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     _dragger = new WindowsDragger(this); 
    } 
} 

Helper Klasse:

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

wo WpfScreen von hier sind: How to get the size of the current screen in WPF?

0

auf Windows-Last oder die Netzlast Fall, dass Sie einen Delegaten verwenden können, die zum Auslösen DragMove() -Funktion.

`private void Grid_Loaded (object sender, RoutedEventArgs e) {

 this.MouseDown += delegate{DragMove();}; 

    }` 
3

hier etwas vereinfachte Code, um die WPF Form rund um den Bildschirm zu ziehen. Möglicherweise haben Sie etwas von diesem Code in verschiedenen Posts gesehen, ich habe ihn so modifiziert, dass er den Anforderungen des WPF-Formulars entspricht.

Denken Sie daran, dass wir die Position des Formulars in MouseLeftButtonDown abrufen müssen, damit wir den Mauszeiger an der gleichen Stelle im Formular halten können, wie wir sie auf dem Bildschirm ziehen.

Sie auch den folgenden Hinweis hinzufügen müssen die Mausposition in Bezug auf den Bildschirm zu bekommen: System.Windows.Forms

Eigenschaften benötigt:

private bool _IsDragInProgress { get; set; } 
private System.Windows.Point _FormMousePosition {get;set;} 

Code:

 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); 
     } 
+0

Es ist seltsam, aber einfache DragMove() in MouseDown-Ereignis funktioniert gut, bis Benutzer Fenster auf der Oberseite des Desktops (über Top 100px) bewegt.Mit Ihrer Lösung kann mein Formular überall dort platziert werden, wo der Benutzer es wünscht. Wenn jemand wissen möchte, ist WindowStyle meines WPF-Formulars None, und OS ist Windows 7. –

+0

Dies lässt das Fenster nur flattern (schnell anzeigen/ausblenden) und springt, wenn ein bestimmtes Steuerelement als Ziehoberfläche ausgewählt wird. Gibt es einen Grund, warum verschiedene Forms.Cursor.Position in einer Methode und e.GetPosition in einer anderen verwendet wird? – StingyJack

+0

@StingyJack das Formular sollte als eine Ziehoberfläche ausgerichtet werden, Steuerelemente wie Schaltflächen sollten das Formular nicht ziehen dürfen. Was die Verwendung von 'e.GetPosition' gegenüber' System.Windows.Forms.Cursor.Position' betrifft, müssen Sie 'System.Windows.Forms.Cursor.Position' in einen' Point' konvertieren. Es wird ungefähr so ​​aussehen. 'this._FormMousePosition = neuer Punkt (System.Windows.Forms.Cursor.Position.X, System.Windows.Forms.Cursor.Position.Y);' Dies funktioniert, ABER das WPF-Formular springt, wenn Sie es anfänglich anklicken. 'this._FormMousePosition = e.GetPosition ((UIElement) this);' bewirkt nicht, dass das Formular springt – TheMiddleMan

Verwandte Themen