2012-11-13 15 views
10

Gibt es eine kluge Art und Weise zu erkennen, ob ein Fenster geschlossen wurde vonWie beim Schließen Handler

  • Ein Benutzer die Taste (X ‚Fenster schließen Schaltfläche geklickt (X)‘ vs. window.close() unterscheiden) in der oberen rechten Ecke des Fensters oder
  • window.Close() wurde programmatisch aufgerufen.

Ich möchte dies in der window.Closing Handler erkennen. Ich könnte eine Flagge setzen, wenn ich window.Close(), aber das ist keine sehr schöne Lösung.

+0

während es möglich sein könnte, dies scheint nicht wie eine gute Idee, sie anders zu behandeln .. Aus UX Sicht Alt-F4/Datei-> Beenden/Schließen mit Schließen-Taste/Schließen programmatisch sollte alle gleich sein .. – stijn

+1

Ich denke, es macht Sinn, wenn Sie die Schließen-Taste drücken, um ein Kind-Fenster zu verbergen, aber das Kind Fenster schließen, wenn Anwendung geschlossen Taste gedrückt. – resp78

Antwort

12

Ich bin mir nicht sicher, ob ich das überhaupt mag, aber es ist eine Frage, die Sie offensichtlich einen Grund haben zu fragen. Wenn Sie im OnClosing-Ereignis eine Stack-Ablaufverfolgung durchführen, können Sie nach dem Window.Close-Ereignis suchen.

protected override void OnClosing(System.ComponentModel.CancelEventArgs e) 
{ 
    bool wasCodeClosed = new StackTrace().GetFrames().FirstOrDefault(x => x.GetMethod() == typeof(Window).GetMethod("Close")) != null; 
    if (wasCodeClosed) 
    { 
     // Closed with this.Close() 
    } 
    else 
    { 
     // Closed some other way. 
    } 

    base.OnClosing(e); 
} 
3

Der Unterschied ist der folgende:

Window.Close() bewirkt, dass WM_CLOSE zu senden Fenster werden.

Alt + F4 und X Taste verursacht WM_SYSCOMMAND Nachricht mit SC_CLOSE Typ. Sie können entscheiden, ob Sie diese Nachricht weiterleiten möchten (und am Ende WM_CLOSE verursachen).

Hier ist ein Stück Code, um diese Nachricht zu erfassen. Return „True“ von Delegierten, wenn Sie möchten Standardverhalten abzubrechen:

class SystemMenu : IDisposable 
{ 
    const int WM_SYSCOMMAND = 0x0112; 
    const int SC_CLOSE = 0xF060; 

    public delegate bool HandleSystemCommand(); 
    HwndSource _source; 
    HandleSystemCommand _handler; 

    public SystemMenu(Window window, HandleSystemCommand handler) 
    { 
     _handler = handler; 
     _source = HwndSource.FromHwnd(new WindowInteropHelper(window).Handle); 
     _source.AddHook(WndProc); 
    } 

    public void Dispose() { 
     _source.RemoveHook(WndProc); 
    } 

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     switch (msg) 
     { 
      case WM_SYSCOMMAND: 
       int command = wParam.ToInt32() & 0xfff0; 
       if (command == SC_CLOSE) 
        handled = _handler(); 
       break; 
      default: 
       break; 
     } 
     return IntPtr.Zero; 
    } 
} 
Verwandte Themen