Jak mogę przenieść moją aplikację WPF na przód pulpitu? Do tej pory próbowałem:
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);
Żadne z nich nie wykonuje zadania ( Marshal.GetLastWin32Error()
mówi, że te operacje zostały zakończone pomyślnie, a atrybuty P / Invoke dla każdej definicji mają SetLastError=true
).
Jeśli utworzę nową pustą aplikację WPF i zadzwonię SwitchToThisWindow
z zegarem, działa ona dokładnie tak, jak się spodziewano, więc nie jestem pewien, dlaczego nie działa w moim oryginalnym przypadku.
Edycja : Robię to w połączeniu z globalnym skrótem klawiszowym.
Odpowiedzi:
Próbuje przenieść okno na pierwszy plan i aktywuje je.
To powinno wystarczyć, chyba że źle zrozumiałem, a ty chcesz zachowania Always on Top. W takim przypadku chcesz:
źródło
Topmost
właściwości, jest złą praktyką, ponieważ może zasłaniać inne wyskakujące okna dialogowe i mieć nieoczekiwane zachowanie.if (myWindow.WindowState == WindowState.Minimized) myWindow.WindowState = WindowState.Normal;
Dziwnie, zachowa również wszystkie zmaksymalizowane okna i nie przywróci ich do stanu normalnego.Znalazłem rozwiązanie, które przenosi okno na górę, ale zachowuje się jak normalne okno:
źródło
Window.Focus()
. Spowoduje to oderwanie się od tego, co użytkownik wpisuje w polu tekstowym, co jest niezwykle frustrujące dla użytkowników końcowych. Powyższy kod działa bez niego dobrze.Jeśli chcesz, aby okno znajdowało się z przodu przy pierwszym ładowaniu, wykonaj następujące czynności:
źródło
Aby było to szybkie kopiowanie-wklejanie -
użyj tej
DoOnProcess
metody „ metody, aby przenieść okno główne procesu” na pierwszy plan (ale nie kradnij fokusu z innych okien)HTH
źródło
process.MainWindowHandle
?hWnd
. FWIWHwndSource
obiekt działał dobrze.Wiem, że to pytanie jest dość stare, ale właśnie natknąłem się na ten precyzyjny scenariusz i chciałem podzielić się wdrożonym przeze mnie rozwiązaniem.
Jak wspomniano w komentarzach na tej stronie, kilka proponowanych rozwiązań nie działa na XP, które muszę wspierać w moim scenariuszu. Chociaż zgadzam się z opinią @Matthew Xaviera, że ogólnie jest to zła praktyka UX, są chwile, w których jest to całkowicie prawdopodobne UX.
Rozwiązanie przeniesienia okna WPF na samą górę zostało mi zapewnione przez ten sam kod, którego używam do zapewnienia globalnego skrótu. Artykuł na blogu Josepha Cooneya zawiera link do jego próbek kodu, który zawiera oryginalny kod.
Wyczyściłem i zmodyfikowałem trochę kod i zaimplementowałem go jako metodę rozszerzenia do System.Windows.Window. Przetestowałem to na XP 32-bitowym i Win7 64-bitowym, oba działają poprawnie.
Mam nadzieję, że ten kod pomoże innym, którzy napotkają ten problem.
źródło
this.Activate()
wydaje się działać czasami.Jeśli użytkownik wchodzi w interakcję z inną aplikacją, przeniesienie Twojej aplikacji na pierwszy plan może być niemożliwe. Zasadniczo proces może oczekiwać ustawienia okna pierwszego planu, tylko jeśli proces ten jest już procesem pierwszego planu. (Microsoft dokumentuje ograniczenia we wpisie MSDN SetForegroundWindow ()) . Jest tak, ponieważ:
źródło
Wiem, że to późna odpowiedź, być może pomocna dla badaczy
źródło
Dlaczego niektóre odpowiedzi na tej stronie są błędne!
Każda zastosowana odpowiedź
window.Focus()
jest nieprawidłowa.window.Focus()
odciągnie uwagę od tego, co użytkownik wpisuje w danym momencie. Jest to niezwykle frustrujące dla użytkowników końcowych, szczególnie jeśli wyskakujące okienka pojawiają się dość często.Każda zastosowana odpowiedź
window.Activate()
jest nieprawidłowa.window.ShowActivated = false
zostanie pominięta, jest błędna.Visibility.Visible
do ukrywania / pokazywania okna, jest niepoprawna.window.Show()
iwindow.Hide()
.Głównie:
Rozwiązanie MVVM
Ten kod jest w 100% zgodny z Citrix (bez pustych obszarów ekranu). Jest testowany zarówno z normalnym WPF, jak i DevExpress.
Ta odpowiedź jest przeznaczona dla każdego przypadku użycia, w którym chcemy małe okno powiadomienia, które zawsze znajduje się przed innymi oknami (jeśli użytkownik wybierze to w preferencjach).
Jeśli ta odpowiedź wydaje się bardziej złożona niż inne, to dlatego, że jest to solidny kod na poziomie przedsiębiorstwa. Niektóre inne odpowiedzi na tej stronie są proste, ale w rzeczywistości nie działają.
XAML - właściwość dołączona
Dodaj tę dołączoną właściwość do dowolnej
UserControl
w oknie. Załączona nieruchomość:Loaded
zdarzenie zostanie uruchomione (w przeciwnym razie nie będzie mógł przeglądać drzewa wizualnego w celu znalezienia okna nadrzędnego).W dowolnym momencie możesz ustawić okno tak, aby było na wierzchu lub nie, odwracając wartość dołączonej właściwości.
C # - Metoda pomocnicza
Stosowanie
Aby tego użyć, musisz utworzyć okno w swoim ViewModel:
Dodatkowe linki
Aby dowiedzieć się, jak upewnić się, że okno powiadomień zawsze przesuwa się z powrotem na widoczny ekran, zobacz moją odpowiedź: W WPF, jak przenieść okno na ekran, jeśli jest poza ekranem? .
źródło
catch (Exception) { }
. Tak, prawda ... I używa kodu, który nie jest nawet wyświetlany w odpowiedzi, takiej jak_dialogService
lubShiftWindowOntoScreenHelper
. Plus prośba o utworzenie okna po stronie viewmodel (co w zasadzie psuje cały wzór MVVM) ...Func<>
powiązanego z ViewModel.Miałem podobny problem z aplikacją WPF, która jest wywoływana z aplikacji Access za pośrednictwem obiektu Shell.
Moje rozwiązanie jest poniżej - działa w XP i Win7 x64 z aplikacją skompilowaną do celu x86.
Wolałbym to zrobić niż symulować klawisz Alt.
źródło
Cóż, ponieważ jest to tak gorący temat ... oto, co działa dla mnie. Wystąpiły błędy, jeśli nie zrobiłem tego w ten sposób, ponieważ Activate () spowoduje błąd, jeśli nie widzisz okna.
Xaml:
Codebehind:
To był dla mnie jedyny sposób na wyświetlenie okna na górze. Następnie aktywuj go, aby móc pisać w polu bez konieczności ustawiania ostrości za pomocą myszy. control.Focus () nie będzie działać, chyba że okno jest aktywne ();
źródło
Cóż, wymyśliłem obejście. Dzwonię z haka na klawiaturę używanego do wprowadzenia skrótu. Wywołanie działa zgodnie z oczekiwaniami, jeśli wstawię go do BackgroundWorker z pauzą. To kludge, ale nie mam pojęcia, dlaczego pierwotnie nie działało.
źródło
Aby wyświetlić JAKIEKOLWIEK otwarte okno, zaimportuj te biblioteki DLL:
oraz w programie Szukamy aplikacji o określonym tytule (wpisz tytuł bez pierwszej litery (indeks> 0))
źródło
IndexOf
zamiast tego nie używać poprawnie?Problemem może być to, że wątek wywołujący twój kod z haka nie został zainicjowany przez środowisko wykonawcze, więc wywołanie metod środowiska wykonawczego nie działa.
Być może możesz spróbować wykonać Invoke, aby wprowadzić kod do wątku interfejsu użytkownika i wywołać kod, który przenosi okno na pierwszy plan.
źródło
Kody te będą działać poprawnie przez cały czas.
Najpierw ustaw aktywowaną procedurę obsługi zdarzeń w XAML:
Dodaj poniższy wiersz do bloku konstruktora okna głównego:
A w aktywowanym module obsługi zdarzeń skopiuj następujące kody:
Te kroki będą działać dobrze i doprowadzą do przodu wszystkie inne okna w oknie ich rodziców.
źródło
Jeśli próbujesz ukryć okno, na przykład minimalizujesz okno, znalazłem to za pomocą
ukryje go poprawnie, a następnie po prostu użyje
pokaże wtedy okno jako najwyżej umieszczony element.
źródło
Chciałem tylko dodać inne rozwiązanie do tego pytania. Ta implementacja działa w moim scenariuszu, w którym CaliBurn jest odpowiedzialny za wyświetlanie głównego okna.
źródło
Pamiętaj, aby nie umieszczać kodu wyświetlającego to okno w module obsługi PreviewMouseDoubleClick, ponieważ aktywne okno powróci do okna, które obsłużyło zdarzenie. Wystarczy umieścić go w module obsługi zdarzeń MouseDoubleClick lub przestać propagować, ustawiając e.Handled na True.
W moim przypadku obsługiwałem PreviewMouseDoubleClick w widoku listy i nie ustawiałem e.Handled = true, a następnie podniosłem zdarzenie MouseDoubleClick, które skupiło się z powrotem do oryginalnego okna.
źródło
Zbudowałem metodę rozszerzenia, aby ułatwić ponowne użycie.
Wezwij konstruktora formularzy
źródło