2009-10-30 18 views
7

El comportamiento predeterminado de una ventana emergente es que si se coloca donde se extendería más allá del borde de la pantalla, la ventana emergente se reposicionará. ¿Hay alguna forma de desactivar este comportamiento?hacer una ventana emergente WPF no vinculada a la pantalla

Tengo una ventana emergente que el usuario puede arrastrar por la pantalla. Sin embargo, cuando llega a los bordes, se atasca. Se queda atascado en el borde y se queda allí hasta que el mouse se arrastra lejos del borde. Además, tengo dos monitores y cuando la ventana emergente es arrastrada al borde de los dos monitores, me sale parpadeante. La ventana emergente parpadea entre los dos monitores.

Respuesta

3

Sólo tiene que utilizar interoperabilidad de mover las ventanas emergentes (arrastrarlos)

Aquí es el código para el pulgar que hará un seguimiento del proceso de arrastrar

región del pulgar

private Thumb mThumb = null; 
    public Thumb Thumb 
    { 
     get { return mThumb; } 
     set 
     { 
      if (mThumb != value) 
      { 
       if (mThumb != null) 
       { 
        DetachThumb(); 
       } 
       mThumb = value; 
       if (mThumb != null) 
       { 
        AttachThumb(); 
       } 
      } 
     } 
    } 

    private void AttachThumb() 
    { 
     Thumb.DragStarted += Thumb_DragStarted; 
     Thumb.DragDelta += Thumb_DragDelta; 
     Thumb.DragCompleted += Thumb_DragCompleted; 
    } 

    private void DetachThumb() 
    { 
     Thumb.DragStarted -= Thumb_DragStarted; 
     Thumb.DragDelta -= Thumb_DragDelta; 
     Thumb.DragCompleted -= Thumb_DragCompleted; 
    } 

    private void Thumb_DragStarted(object sender, DragStartedEventArgs e) 
    { 
     mIsThumbDragging = true; 
     mPreviousDiffX = 0; 
     mPreviousDiffY = 0; 
    } 

    private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) 
    { 
     if (mIsMoving) 
     { 
      return; 
     } 
     mIsMoving = true; 
     try 
     { 
      if (mIsThumbDragging) 
      { 
       var doubleDetaX = e.HorizontalChange + mPreviousDiffX; 
       var doubleDetaY = e.VerticalChange + mPreviousDiffY; 

       var deltaX = (int)doubleDetaX; 
       var deltaY = (int)doubleDetaY; 

       mPreviousDiffX = (double)deltaX - doubleDetaX; 
       mPreviousDiffY = (double)deltaY - doubleDetaY; 

       HostPopup.Move(deltaX, deltaY); 
      } 
     } 
     finally 
     { 
      mIsMoving = false; 
     } 
    } 

    private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e) 
    { 
     mIsThumbDragging = false; 
    } 

    #endregion 

clase El HostPopup es subclase de ventanas emergentes , y tiene los siguientes métodos que utilizan la interoperabilidad para mover la ventana:

[DllImport("user32.dll", SetLastError = true)] 
    internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); 

    internal void Move(int deltaX, int deltaY) 
    { 
     if (mIsMoving) 
     { 
      return; 
     } 
     mIsMoving = true; 
     try 
     { 
      if (Child == null) 
       return; 

      var hwndSource = (PresentationSource.FromVisual(Child)) as HwndSource; 

      if (hwndSource == null) 
       return; 
      var hwnd = hwndSource.Handle; 

      RECT rect; 

      if (!GetWindowRect(hwnd, out rect)) 
       return; 

      MoveWindow(hwnd, rect.Left + deltaX, rect.Top + deltaY, (int)Width, (int)Height, true); 
     } 
     finally 
     { 
      mIsMoving = false; 
     } 
    } 
+1

¿Alguien puede explicar con más detalle cómo implementar esto? ¿Cómo obtengo acceso a la subclase HostPopup? ¿Dónde reside el método GetWindowRect()? – Saggio

2

Si desea que la ventana emergente se comporte más como una ventana, simplemente crearía una ventana en lugar de una ventana emergente.

Tener una ventana emergente que no se posiciona como una ventana emergente estándar, y le permite arrastrarlo por la pantalla, simplemente parece una receta de baja usabilidad y confusión.

+3

Desafortunadamente, la Esta es la funcionalidad de una ventana emergente que una ventana no tiene y es más importante para mí que la libertad de movimiento. Supongo que tendré que restringir el movimiento, así que no hay posibilidad de ir más allá de los límites de la pantalla y, por lo tanto, no hay reposicionamiento ni parpadeo. Gracias por la info. –

+1

de acuerdo. Quiero que la ventana emergente siga la ventana y evite la entrada en un control WinForm alojado en la aplicación WPF (esencialmente un indicador de ocupado) y si la ventana se arrastra fuera de la pantalla, la ventana emergente no seguirá la ventana más allá de los límites de la pantalla. –

+0

Otro punto de datos sobre esto. A veces Popup es preferible a Window para arrastrar contenido, ya que al abrir una ventana en Windows 10 con modo Tablet activará la acción de división de pantalla de Win10 e interrumpirá el arrastre. (Contexto: estoy usando Popup temporalmente como una ventana de comentarios de arrastrar, no parte permanente de la interfaz de usuario) – jschroedl

Cuestiones relacionadas