2010-07-18 8 views
8

Ho una finestra principale meno finestra di WPF. Sto cercando di farlo in modo che l'utente finale possa trascinare la finestra.Modo per rendere trascinabile una finestra WPF Windowless senza ottenere InvalidOperationException

ho aggiunto quanto segue per il costruttore della finestra:

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

Il problema è, ho una finestra di dialogo che si apre con due pulsanti. Quando faccio clic su uno di questi pulsanti, viene visualizzato un InvalidOperationException non gestito con il messaggio "È possibile chiamare DragMove solo quando il pulsante principale del mouse non è attivo."

Questo pone alcune domande: Perché un evento di mouse in una finestra di dialogo ha qualcosa a che fare con questo? Come posso fare questo senza questa eccezione?

Grazie!

+0

Ho anche finestre con meno bordi con pulsanti e lascia che l'utente lo trascini premendo il pulsante sinistro del mouse e funziona perfettamente. Fornire un esempio di codice minimo ma completo che mostri questo comportamento. –

risposta

7

Il modo "corretto" per rendere mobile una finestra senza bordi è restituire HTCAPTION nel messaggio WM_NCHITTEST. Il seguente codice mostra come farlo. Si noti che si desidera restituire HTCLIENT se il cursore si trova su determinati elementi visivi della finestra, quindi questo codice è solo per iniziare.

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

Se si tenta di "restituire HTCAPTION nel messaggio WM_NCHITTEST" come suggerisce Tergiver, i pulsanti non saranno cliccabili, ad esempio l'evento click non funzionerà per i pulsanti. Qualcuno ha una soluzione alternativa per questo? –

+0

Nota che ho affermato che quel codice era solo un punto di partenza. Non è possibile restituire HTCAPTION per l'intero rettangolo della finestra come fa il codice sopra. Devi decidere quali aree della tua finestra non dovrebbero essere aree 'didascalia'. Questo potrebbe essere semplice come un rettangolo nell'area di controllo, o complesso come camminare sull'albero visivo e cercare controlli. – Tergiver

0

C'è un progetto di Microsoft che gestisce tutto lo stile "senza finestre" e molto altro ancora, ed è opensource, si potrebbe desiderare di dare un'occhiata a http://code.msdn.microsoft.com/WPFShell. Sto utilizzando un'applicazione finanziaria commerciale e non ho ancora riscontrato problemi su nessuna versione di Windows.

1

Impostare l'atrribute MouseDown della finestra o qualsiasi altro controllo che si desidera utilizzare:

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

E implementarla nel codice dietro in questo modo:

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

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

0

è possibile ignorare il metodo originale:

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); 
     } 
    } 
Problemi correlati