2009-05-15 15 views
14

sto provando a creare un modulo C# WPF in cui posso trascinarlo sullo schermo facendo clic su di esso e muovendolo con il mouse. le caratteristiche delle forme includono essere completamente trasparenti e contenenti solo un'immagine. Detto questo, lo stile della finestra è none e non viene visualizzato nella barra delle applicazioni. Quindi in sostanza tutto ciò che puoi vedere quando l'app è in esecuzione è una piccola immagine e idealmente voglio essere in grado di trascinarlo sul desktop se faccio clic e tengo premuto il pulsante sinistro del mouse per spostarlo.Trascinare un modulo WPF sul desktop

Qualcuno sa un modo semplice in cui posso realizzare questo o ho trascurato una build in funzione?

Grazie.

+0

Grazie mille, stavo solo guardando 2 giorni per una tale risposta :) –

risposta

18

È possibile utilizzare il metodo Window.DragMove nell'evento del mouse della finestra.

+0

potresti fornire un codice exmaple di come potrei fare questo? – Grant

+0

Esiste un esempio di codice nella documentazione per il metodo DragMove che mostra esattamente cosa si sta tentando di fare ma è letteralmente lungo 3 righe - gestisce l'evento MouseLeftButtonDown della finestra, chiama il metodo DragMove sulla finestra. – Josh

20

risposte precedenti ha colpito sulla risposta, ma l'esempio completo è questo:

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

Basta usare MouseLeftButtonDown e non è necessario alcun controllo –

1

Se, come me, vogliono avere un po 'più di controllo sulla DoDragMove() - dice, per avere la la finestra rimane sempre nel bordo del desktop corrente, l'ho fatto.

Usage:

public partial class MainWindow : Window 
{ 
    private WindowsDragger _dragger; 

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

classe helper:

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

dove WpfScreen è da qui: How to get the size of the current screen in WPF?

0

sulle finestre del carico o l'evento di caricamento della griglia è possibile utilizzare un delegato per attivare il Funzione DragMove().

`(object sender, RoutedEventArgs e) vuoto Grid_Loaded privato {

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

    }` 
3

Ecco il codice semplificato per trascinare il modulo WPF intorno al vostro schermo. Potresti aver visto parte di questo codice su diversi post, l'ho appena modificato per adattarlo alle esigenze di trascinamento del modulo WPF.

Ricordare che è necessario prendere la posizione del modulo su MouseLeftButtonDown, in modo da mantenere il puntatore del mouse posizionato nello stesso punto del modulo mentre lo si trascina sullo schermo.

Sarà inoltre necessario aggiungere il seguente riferimento per ottenere la posizione del mouse rispetto allo schermo: System.Windows.Forms

proprietà necessarie:

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

Codice:

 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

È strano, ma DragMove() semplice nell'evento MouseDown funziona correttamente, finché l'utente sposta la finestra sul lato superiore del desktop (circa 100px superiore).Con la tua soluzione il mio modulo può essere posizionato ovunque l'utente desideri. Se qualcuno vuole sapere, WindowStyle del mio modulo WPF è None, e il sistema operativo è Windows 7. –

+0

Questo rende solo la finestra fluttuante (mostra/nascondi rapidamente) e nervosa quando si mira a un controllo specifico come superficie di trascinamento. C'è qualche ragione per cui usare diversi Forms.Cursor.Position in un metodo e e.GetPosition in un altro? – StingyJack

+0

@StingyJack il modulo deve essere indirizzato come superficie di trascinamento, i controlli come i pulsanti non dovrebbero essere autorizzati a trascinare il modulo. Per quanto riguarda l'uso di 'e.GetPosition' contro' System.Windows.Forms.Cursor.Position', è necessario convertire 'System.Windows.Forms.Cursor.Position' in un' Punto'. Assomiglierà a questo. 'this._FormMousePosition = new Point (System.Windows.Forms.Cursor.Position.X, System.Windows.Forms.Cursor.Position.Y);' Funziona, MA il salto del modulo WPF quando inizialmente si fa clic su di esso. 'this._FormMousePosition = e.GetPosition ((UIElement) this);' non fa saltare il modulo – TheMiddleMan

Problemi correlati