2009-05-15 37 views
14

Estoy tratando de hacer un formulario C# WPF donde pueda arrastrarlo por la pantalla haciendo clic en él y moviéndolo con el mouse. las características de las formas incluyen ser completamente transparente y contener solo una imagen. Dicho esto, el estilo de ventana es none y no se muestra en la barra de tareas. Entonces, básicamente, todo lo que puede ver cuando la aplicación se está ejecutando es una pequeña imagen, y lo ideal sería que yo pueda arrastrarlo por el escritorio si hago clic y mantengo presionado el botón izquierdo del mouse y lo muevo.Arrastrar un formulario WPF alrededor del escritorio

¿Alguien sabe de una manera simple que puedo lograr esto o he pasado por alto una función de compilación?

Gracias.

+0

Muchas gracias, solo estaba buscando 2 días para una respuesta :) –

Respuesta

18

Puede usar el método Window.DragMove en el evento del mouse de la ventana.

+0

¿podría proporcionar un código como ejemplo de cómo podría hacer esto? – Grant

+0

Hay un ejemplo de código en la documentación del método DragMove que muestra exactamente lo que está intentando hacer, pero literalmente tiene 3 líneas: maneje el evento MouseLeftButtonDown de la ventana, llame al método DragMove en la ventana. – Josh

20

respuestas anteriores golpearon en la respuesta, pero el ejemplo completo es la siguiente:

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

Simplemente use MouseLeftButtonDown y no se necesita verificar –

1

Si, como yo, quieren tener un poco más de control sobre el DoDragMove() - dice, para tener la ventana siempre permanecer en el borde del escritorio actual, he hecho esto.

Uso:

public partial class MainWindow : Window 
{ 
    private WindowsDragger _dragger; 

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

clase auxiliar:

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

donde WpfScreen es de aquí: How to get the size of the current screen in WPF?

0

en la carga de ventanas o el evento carga de la red puede utilizar un delegado para activar el La función DragMove().

`(object sender, RoutedEventArgs e) vacío Grid_Loaded privada {

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

    }` 
3

Aquí hay un código simplificado para arrastrar la forma de WPF alrededor de su pantalla. Es posible que haya visto algo de este código en diferentes publicaciones, simplemente lo modifiqué para adaptarlo a las necesidades de arrastrar el formulario WPF.

Tenga en cuenta que tenemos que tomar la posición de formulario en MouseLeftButtonDown, para que podamos mantener el puntero del mouse (ratón) colocado en el mismo lugar en el formulario mientras lo estamos arrastrando por la pantalla.

También tendrá que añadir la siguiente referencia para obtener la posición del ratón respecto a la pantalla: System.Windows.Forms

propiedades necesarias:

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

Código:

 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 extraño, pero el simple DragMove() en el evento MouseDown funciona bien, hasta que el usuario mueve la ventana en la parte superior del escritorio (aproximadamente 100px).Con su solución, mi formulario puede colocarse donde el usuario lo desee. Si alguien quiere saber, WindowStyle de mi formulario WPF es None, y el sistema operativo es Windows 7. –

+0

Esto hace que la ventana revolotee (mostrar/ocultar rápidamente) y salte cuando se dirige a un control específico como una superficie de arrastre. ¿Hay alguna razón por la cual usar Forms.Cursor.Position diferente en un método y e.GetPosition en otro? – StingyJack

+0

@StingyJack el formulario debe estar orientado como una superficie de arrastre, los controles como los botones no se debe permitir que arrastren el formulario. En cuanto a usar 'e.GetPosition' contra' System.Windows.Forms.Cursor.Position', necesitará convertir 'System.Windows.Forms.Cursor.Position' en' Point'. Se verá algo como esto. 'this._FormMousePosition = new Point (System.Windows.Forms.Cursor.Position.X, System.Windows.Forms.Cursor.Position.Y);' Esto funciona, PERO el WPF forma salto cuando inicialmente hace clic en él. 'this._FormMousePosition = e.GetPosition ((UIElement) this);' no causa que la forma salte – TheMiddleMan

Cuestiones relacionadas