Wie kann ich meine WPF-Anwendung an die Vorderseite des Desktops bringen? Bisher habe ich versucht:
SwitchToThisWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle, true);
SetWindowPos(new WindowInteropHelper(Application.Current.MainWindow).Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
SetForegroundWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);
Keiner von Marshal.GetLastWin32Error()
ihnen erledigt den Job ( besagt, dass diese Vorgänge erfolgreich abgeschlossen wurden und die P / Invoke-Attribute für jede Definition vorhanden sind SetLastError=true
).
Wenn ich eine neue leere WPF-Anwendung erstelle und SwitchToThisWindow
mit einem Timer aufrufe, funktioniert sie genau wie erwartet, sodass ich nicht sicher bin, warum sie in meinem ursprünglichen Fall nicht funktioniert.
Edit : Ich mache das in Verbindung mit einem globalen Hotkey.
Antworten:
Versucht, das Fenster in den Vordergrund zu bringen und aktiviert es.
Das sollte den Trick machen, es sei denn, ich habe es falsch verstanden und Sie wollen immer das Top-Verhalten. In diesem Fall möchten Sie:
quelle
Topmost
Eigenschaft, ist jedoch eine schlechte Vorgehensweise, da sie andere Popup-Dialoge verdecken und unerwartetes Verhalten aufweisen kann.if (myWindow.WindowState == WindowState.Minimized) myWindow.WindowState = WindowState.Normal;
Seltsamerweise werden auch alle maximierten Fenster beibehalten und nicht in den normalen Zustand zurückgesetzt.Ich habe eine Lösung gefunden, die das Fenster nach oben bringt, aber es verhält sich wie ein normales Fenster:
quelle
Window.Focus()
. Dadurch wird der Fokus von dem entfernt, was der Benutzer gerade in ein Textfeld eingibt, was für Endbenutzer wahnsinnig frustrierend ist. Der obige Code funktioniert ohne ihn einwandfrei.Wenn das Fenster beim ersten Laden vorne sein muss, sollten Sie Folgendes verwenden:
quelle
So erstellen Sie ein schnelles Kopieren und Einfügen:
Verwenden Sie das
DoOnProcess
Hauptfenster dieser Klasse, um den Prozess in den Vordergrund zu verschieben (aber nicht, um den Fokus von anderen Fenstern zu stehlen).HTH
quelle
process.MainWindowHandle
?hWnd
. FWIW einHwndSource
Objekt hat gut funktioniert.Ich weiß, dass diese Frage ziemlich alt ist, aber ich bin gerade auf dieses genaue Szenario gestoßen und wollte die von mir implementierte Lösung teilen.
Wie in den Kommentaren auf dieser Seite erwähnt, funktionieren einige der vorgeschlagenen Lösungen nicht unter XP, was ich in meinem Szenario unterstützen muss. Obwohl ich dem Gefühl von @Matthew Xavier zustimme, dass dies im Allgemeinen eine schlechte UX-Praxis ist, gibt es Zeiten, in denen es sich durchaus um eine plausible UX handelt.
Die Lösung, um ein WPF-Fenster nach oben zu bringen, wurde mir tatsächlich durch denselben Code bereitgestellt, mit dem ich den globalen Hotkey bereitstelle. Ein Blog-Artikel von Joseph Cooney enthält einen Link zu seinen Codebeispielen , der den Originalcode enthält.
Ich habe den Code ein wenig bereinigt und geändert und ihn als Erweiterungsmethode für System.Windows.Window implementiert. Ich habe dies auf XP 32 Bit und Win7 64 Bit getestet, die beide korrekt funktionieren.
Ich hoffe, dieser Code hilft anderen, die auf dieses Problem stoßen.
quelle
this.Activate()
scheint nur einige Male zu funktionieren.Wenn der Benutzer mit einer anderen Anwendung interagiert, ist es möglicherweise nicht möglich, Ihre Anwendung in den Vordergrund zu rücken. In der Regel kann ein Prozess nur dann damit rechnen, das Vordergrundfenster festzulegen, wenn dieser Prozess bereits der Vordergrundprozess ist. (Microsoft dokumentiert die Einschränkungen im MSDN-Eintrag SetForegroundWindow () .) Dies liegt daran, dass:
quelle
Ich weiß, dass dies eine späte Antwort ist, vielleicht hilfreich für Forscher
quelle
Warum einige der Antworten auf dieser Seite falsch sind!
Jede Antwort, die verwendet
window.Focus()
wird , ist falsch.window.Focus()
wird der Fokus von dem entfernt, was der Benutzer gerade eingibt. Dies ist für Endbenutzer wahnsinnig frustrierend, insbesondere wenn die Popups ziemlich häufig auftreten.Jede Antwort, die verwendet
window.Activate()
wird , ist falsch.window.ShowActivated = false
wird , ist falsch.Visibility.Visible
zum Ausblenden / Anzeigen des Fensters verwendet wird, ist falsch.window.Show()
undwindow.Hide()
.Im Wesentlichen:
MVVM-Lösung
Dieser Code ist 100% kompatibel mit Citrix (keine leeren Bereiche des Bildschirms). Es wird sowohl mit normalem WPF als auch mit DevExpress getestet.
Diese Antwort ist für jeden Anwendungsfall vorgesehen, in dem ein kleines Benachrichtigungsfenster angezeigt werden soll, das sich immer vor anderen Fenstern befindet (sofern der Benutzer dies in den Einstellungen auswählt).
Wenn diese Antwort komplexer erscheint als die anderen, liegt dies daran, dass es sich um robusten Code auf Unternehmensebene handelt. Einige der anderen Antworten auf dieser Seite sind einfach, funktionieren aber nicht.
XAML - Angehängte Eigenschaft
Fügen Sie diese angehängte Eigenschaft zu einem beliebigen
UserControl
Element im Fenster hinzu. Die beigefügte Eigenschaft wird:Loaded
Ereignis ausgelöst wird (andernfalls kann der visuelle Baum nicht nachgeschlagen werden, um das übergeordnete Fenster zu finden).Sie können das Fenster jederzeit so einstellen, dass es vorne ist oder nicht, indem Sie den Wert der angehängten Eigenschaft umdrehen.
C # - Hilfsmethode
Verwendung
Um dies zu verwenden, müssen Sie das Fenster in Ihrem ViewModel erstellen:
Zusätzliche Links
Tipps, wie Sie sicherstellen können, dass ein Benachrichtigungsfenster immer wieder auf den sichtbaren Bildschirm verschoben wird , finden Sie in meiner Antwort: Wie kann in WPF ein Fenster auf den Bildschirm verschoben werden, wenn es nicht auf dem Bildschirm angezeigt wird? .
quelle
catch (Exception) { }
. Ja, richtig ... und es wird Code verwendet, der in der Antwort nicht einmal wie_dialogService
oder angezeigt wirdShiftWindowOntoScreenHelper
. Außerdem bitten Sie darum, das Fenster auf der Seite des Ansichtsmodells zu erstellen (was im Grunde das gesamte MVVM-Muster bricht) ...Func<>
das an das ViewModel gebunden ist.Ich hatte ein ähnliches Problem mit einer WPF-Anwendung, die von einer Access-Anwendung über das Shell-Objekt aufgerufen wird.
Meine Lösung ist unten - funktioniert in XP und Win7 x64 mit App auf x86-Ziel kompiliert.
Ich würde das viel lieber tun, als einen Alt-Tab zu simulieren.
quelle
Nun, da dies ein so heißes Thema ist ... hier ist, was für mich funktioniert. Ich habe Fehler erhalten, wenn ich es nicht so gemacht habe, weil Activate () bei Ihnen einen Fehler macht, wenn Sie das Fenster nicht sehen können.
Xaml:
Codebehind:
Dies war der einzige Weg für mich, das Fenster oben zu zeigen. Aktivieren Sie es dann, damit Sie das Feld eingeben können, ohne den Fokus mit der Maus einstellen zu müssen. control.Focus () funktioniert nur, wenn das Fenster Active () ist.
quelle
Nun, ich habe eine Lösung gefunden. Ich rufe über einen Tastatur-Hook an, mit dem ein Hotkey implementiert wird. Der Aufruf funktioniert wie erwartet, wenn ich ihn mit einer Pause in einen BackgroundWorker stelle. Es ist ein Kludge, aber ich habe keine Ahnung, warum es ursprünglich nicht funktioniert hat.
quelle
Um JEDES aktuell geöffnete Fenster anzuzeigen, importieren Sie diese DLL:
und im Programm Wir suchen nach App mit angegebenem Titel (Titel ohne Anfangsbuchstaben schreiben (Index> 0))
quelle
IndexOf
stattdessen richtig verwenden?Das Problem könnte sein, dass der Thread, der Ihren Code vom Hook aus aufruft, nicht von der Laufzeit initialisiert wurde, sodass das Aufrufen von Laufzeitmethoden nicht funktioniert.
Vielleicht könnten Sie versuchen, einen Aufruf durchzuführen, um Ihren Code im UI-Thread zu marshallen und Ihren Code aufzurufen, der das Fenster in den Vordergrund rückt.
quelle
Diese Codes funktionieren immer einwandfrei.
Stellen Sie zunächst den aktivierten Event-Handler in XAML ein:
Fügen Sie Ihrem Konstruktionsblock für das Hauptfenster die folgende Zeile hinzu:
Und kopieren Sie im aktivierten Event-Handler die folgenden Codes:
Diese Schritte funktionieren einwandfrei und bringen alle anderen Fenster in das Fenster ihrer Eltern.
quelle
Wenn Sie versuchen, das Fenster auszublenden, zum Beispiel das Fenster zu minimieren, habe ich festgestellt, dass mit
wird es richtig ausblenden, dann einfach mit
Anschließend wird das Fenster erneut als oberstes Element angezeigt.
quelle
Ich wollte nur eine weitere Lösung für diese Frage hinzufügen. Diese Implementierung funktioniert für mein Szenario, in dem CaliBurn für die Anzeige des Hauptfensters verantwortlich ist.
quelle
Denken Sie daran, den Code, der dieses Fenster anzeigt, nicht in einen PreviewMouseDoubleClick-Handler einzufügen, da das aktive Fenster wieder zu dem Fenster wechselt, das das Ereignis behandelt hat. Legen Sie es einfach in den MouseDoubleClick-Ereignishandler oder stoppen Sie das Sprudeln, indem Sie e.Handled auf True setzen.
In meinem Fall habe ich den PreviewMouseDoubleClick in einer Listenansicht verarbeitet und nicht e.Handled = true gesetzt, dann wurde das MouseDoubleClick-Ereignis ausgelöst, bei dem der Fokus wieder auf das ursprüngliche Fenster gerichtet war.
quelle
Ich habe eine Erweiterungsmethode entwickelt, um die Wiederverwendung zu vereinfachen.
Rufen Sie den Formularkonstruktor auf
quelle