2009-05-15 13 views
14

Próbuję utworzyć formularz C# WPF, gdzie mogę przeciągnąć go po ekranie, klikając go i poruszając się za pomocą myszy. cechy formy obejmują bycie całkowicie przezroczystym i zawierającym tylko jeden obraz. Mówi się, że styl okna nie ma i nie jest wyświetlany na pasku zadań. Zasadniczo wszystko, co widzisz, gdy aplikacja jest uruchomiona, to mały obraz - i najlepiej, jeśli chcę, aby móc przeciągnąć go po pulpicie, gdy kliknę i przytrzymam lewy przycisk myszy i poruszę nim.Przeciągnij formularz WPF wokół pulpitu

Czy ktoś wie w prosty sposób mogę tego dokonać lub czy przeoczyłem funkcję kompilacji?

Dzięki.

+0

Wielkie dzięki, szukałem tylko 2 dni na taką odpowiedź :) –

Odpowiedz

18

Możesz użyć metody Window.DragMove w przypadku zdarzenia myszy w oknie.

+0

czy mógłbyś podać przykładowy kod jak mogłem to zrobić? – Grant

+0

Istnieje przykład kodu w dokumentacji metody DragMove, która pokazuje dokładnie to, co próbujesz zrobić, ale ma długość dosłownie 3 linii - obsłużyć zdarzenie MouseLeftButtonDown w oknie, wywołać metodę DragMove w oknie. – Josh

20

poprzednich odpowiedzi trafić na odpowiedź, ale pełny przykład to:

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

Po prostu użyj MouseLeftButtonDown i nie trzeba sprawdzać –

1

Jeśli, tak jak ja, chcą mieć trochę więcej kontroli o DoDragMove() - mówi, aby mieć okno zawsze pozostaje na granicy bieżącego pulpitu, zrobiłem to.

Zastosowanie:

public partial class MainWindow : Window 
{ 
    private WindowsDragger _dragger; 

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

Helper Klasa:

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

gdzie WpfScreen jest stąd: How to get the size of the current screen in WPF?

0

od obciążenia systemu Windows lub zdarzenie obciążenia sieci można użyć delegata do wyzwalania Funkcja DragMove().

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

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

    }` 
3

Oto uproszczony kod przeciągnąć formularz WPF wokół ekranu. Być może widziałeś niektóre z tego kodu w różnych postach, po prostu zmodyfikowałem go tak, aby pasował do potrzeb przeciągania formularza WPF.

Należy pamiętać, że musimy chwycić pozycję formularza na MouseLeftButtonDown, dzięki czemu możemy utrzymywać wskaźnik myszy w tym samym miejscu na formularzu, ponieważ przeciągamy go po ekranie.

Należy również dodać następujące odniesienia, aby uzyskać pozycji myszy względem ekranu: System.Windows.Forms

właściwości potrzebne:

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

Kod:

 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

To dziwne, ale proste DragMove() w zdarzeniu MouseDown działa dobrze, dopóki użytkownik nie przeniesie okna na wierzch pulpitu (około 100px).Dzięki Twojemu rozwiązaniu mój formularz można umieścić w dowolnym miejscu. Jeśli ktoś chce wiedzieć, WindowStyle z mojego formularza WPF jest Brak, a system operacyjny to Windows 7. –

+0

To powoduje, że okno trzepotanie (pokaż/ukryj szybko) i skakać podczas kierowania określonego kontrolowania jako powierzchni przeciągania. Czy istnieje jakiś powód, dla którego przy użyciu różnych Forms.Cursor.Position w jednej metodzie i e.GetPosition w innym? – StingyJack

+0

@StingyJack formularz powinien być ukierunkowany jako powierzchnia przeciągania, elementy sterujące, takie jak przyciski, nie powinny mieć możliwości przeciągania formularza. Jeśli chodzi o użycie 'e.GetPosition' kontra' System.Windows.Forms.Cursor.Position', będziesz musiał przekonwertować 'System.Windows.Forms.Cursor.Position' na' Point'. Będzie wyglądać mniej więcej tak. 'this._FormMousePosition = new Point (System.Windows.Forms.Cursor.Position.X, System.Windows.Forms.Cursor.Position.Y);' To działa, ALE skok formularza WPF następuje po pierwszym kliknięciu. 'this._FormMousePosition = e.GetPosition ((UIElement) this);' nie powoduje przeskoczenia formularza – TheMiddleMan

Powiązane problemy