2010-07-18 19 views
8

Tengo una ventana principal menos WPF. Estoy tratando de hacerlo para que el usuario final pueda arrastrar la ventana.Forma de hacer que una ventana WPF sin ventana sea arrastrable sin obtener InvalidOperationException

He añadido lo siguiente al constructor de la ventana:

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

El problema es, tengo un cuadro de diálogo que se abre con dos botones. Cuando hago clic en uno de estos botones, obtengo una InvalidOperationException no controlada con el mensaje "Solo se puede llamar a DragMove cuando el botón primario del mouse está desactivado".

Esto plantea algunas preguntas: ¿Por qué un evento de mousedown en un diálogo tiene algo que ver con esto? ¿Cómo puedo hacer esto sin esta excepción?

Gracias!

+0

También tengo ventanas con botones en los bordes y dejo que el usuario la arrastre presionando el botón izquierdo del mouse y funciona bien. Proporcione un ejemplo de código mínimo pero completo que muestre este comportamiento. –

Respuesta

7

La forma 'correcta' de mover una ventana sin bordes es devolver HTCAPTION en el mensaje WM_NCHITTEST. El siguiente código muestra cómo hacerlo. Tenga en cuenta que querrá devolver HTCLIENT si el cursor está sobre algunos de los elementos visuales de su ventana, por lo que este código es solo para comenzar.

http://msdn.microsoft.com/en-us/library/ms645618(VS.85).aspx

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnSourceInitialized(EventArgs e) 
    { 
     HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(this); 
     hwndSource.AddHook(WndProcHook); 
     base.OnSourceInitialized(e); 
    } 

    private static IntPtr WndProcHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handeled) 
    { 
     if (msg == 0x0084) // WM_NCHITTEST 
     { 
      handeled = true; 
      return (IntPtr)2; // HTCAPTION 
     } 
     return IntPtr.Zero; 
    } 
} 
+0

Si intenta "devolver HTCAPTION en el mensaje WM_NCHITTEST" como sugiere Tergiver, no se podrá hacer clic en los botones, es decir, el evento de clic no funcionará para los botones. ¿Alguien tiene una solución para esto? –

+0

Tenga en cuenta que afirmé que ese código era solo un punto de partida. No puede devolver HTCAPTION para todo el rectángulo de su ventana como lo hace el código anterior. Debe decidir qué área (s) de su ventana no deben ser áreas de 'título'. Esto podría ser tan simple como un rectángulo en su área de control, o tan complejo como caminar por el árbol visual y buscar controles. – Tergiver

0

Hay un proyecto de Microsoft que se encarga de todo el estilo "ventanas" y mucho más, y es de código abierto, es posible que desee echar un vistazo a http://code.msdn.microsoft.com/WPFShell. Estoy usando una aplicación financiera comercial, y todavía no he encontrado problemas en ninguna versión de Windows.

1

Ajuste el atrribuya MouseDown de la ventana o cualquier otro control que desea utilizar:

<TextBlock Grid.Column="0" HorizontalAlignment="Stretch" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" >Handy Dandy</TextBlock> 

Y ponerlo en práctica en el código detrás de la siguiente manera:

private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    this.DragMove(); 
} 

Desde: http://www2.suddenelfilio.net/2007/01/19/wpf-draggable-windowless-windows/

0

puede anular el método original:

public new void DragMove() 
    { 
     if (this.WindowState == WindowState.Normal) 
     { 
      SendMessage(hs.Handle, WM_SYSCOMMAND, (IntPtr)0xf012, IntPtr.Zero); 
      SendMessage(hs.Handle, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero); 
     } 
    } 
Cuestiones relacionadas