Bawa jendela ke depan di WPF

214

Bagaimana saya bisa membawa aplikasi WPF saya ke depan desktop? Sejauh ini saya sudah mencoba:

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);

Tidak ada yang melakukan pekerjaan ( Marshal.GetLastWin32Error()mengatakan operasi ini selesai dengan sukses, dan atribut P / Invoke untuk setiap definisi memang memiliki SetLastError=true).

Jika saya membuat aplikasi WPF kosong baru, dan telepon SwitchToThisWindow dengan timer, itu berfungsi persis seperti yang diharapkan, jadi saya tidak yakin mengapa itu tidak berfungsi dalam kasus asli saya.

Sunting : Saya melakukan ini bersama dengan hotkey global.

Faktor Mystic
sumber
Sudahkah Anda memverifikasi bahwa MainWindow adalah jendela yang Anda inginkan? Dari MSDN: MainWindow secara otomatis diatur dengan referensi ke objek Window pertama yang akan dipakai di AppDomain.
Todd White
Pemikiran yang bagus, tetapi itu adalah satu-satunya Jendela dalam aplikasi.
Factor Mystic
Bisakah Anda memberikan sedikit kode konteks?
Todd White

Jawaban:

314
myWindow.Activate();

Mencoba untuk membawa jendela ke latar depan dan mengaktifkannya.

Itu harus melakukan trik, kecuali saya salah paham dan Anda ingin perilaku Selalu di Atas. Dalam hal ini yang Anda inginkan:

myWindow.TopMost = true;
Morten Christiansen
sumber
14
Saya hanya menggunakan myWindow.Show () dan kadang-kadang tidak di atas. Saya melakukan panggilan ke myWindow.Activate () segera setelah itu dan berhasil.
Bermo
4
Aktifkan kadang-kadang tidak berfungsi pada Windows XP. Saya merekomendasikan jawaban @Matthew Xavier.
Lex Li
Agak aneh, karena secara default ShowActivated aktif.
greenoldman
1
Jawaban pertama itu bagus, terima kasih untuk itu! Tetapi baris kedua kode, menggunakan Topmostproperti adalah praktik yang buruk karena dapat mengaburkan dialog popup lainnya dan memiliki perilaku tak terduga.
Jonathan Perry
2
Sebenarnya itu bisa dilakukan dengan ini: if (myWindow.WindowState == WindowState.Minimized) myWindow.WindowState = WindowState.Normal;Anehnya itu juga akan mempertahankan semua jendela yang Dimaksimalkan dan tidak mengembalikannya ke keadaan Normal.
r41n
168

Saya telah menemukan solusi yang membawa jendela ke atas, tetapi berperilaku seperti jendela normal:

if (!Window.IsVisible)
{
    Window.Show();
}

if (Window.WindowState == WindowState.Minimized)
{
    Window.WindowState = WindowState.Normal;
}

Window.Activate();
Window.Topmost = true;  // important
Window.Topmost = false; // important
Window.Focus();         // important
Jader Dias
sumber
1
Petunjuk bagus! TopMost membuat keajaiban terjadi pada Windows 7 jika jendela sudah terbuka, tetapi di bawah jendela lain.
gsb
Ini juga membantu saya. Berkat gsb untuk komentar tambahan tentang apa yang tampak seperti penggunaan TopMost yang aneh!
Jen
1
Terima kasih - perbaikannya pendek dan manis.
code4life
2
Dalam kasus saya, Window.Activate () dan Window.Focus () sudah cukup. Pengaturan Window.TopMost tidak perlu.
virious
6
Jangan gunakan Window.Focus(). Ini akan mengambil fokus dari apa yang saat ini diketik pengguna dalam kotak teks, yang membuat frustasi bagi pengguna akhir. Kode di atas berfungsi dengan baik tanpa itu.
Contango
32

Jika Anda perlu jendela berada di depan saat pertama kali memuat maka Anda harus menggunakan yang berikut:

private void Window_ContentRendered(object sender, EventArgs e)
{
    this.Topmost = false;
}

private void Window_Initialized(object sender, EventArgs e)
{
    this.Topmost = true;
}
Amir
sumber
1
Jika Anda mengembangkan sesuatu yang mirip dengan Launchy ( launchy.net ) di C #, Anda harus memperhatikan bahwa jawaban ini hampir tidak berguna.
Lex Li
21

Untuk menjadikan ini salinan-tempel yang cepat -
Gunakan kelas ini ' DoOnProcessmetode untuk memindahkan proses' jendela utama ke latar depan (tetapi tidak mencuri fokus dari jendela lain)

public class MoveToForeground
{
    [DllImportAttribute("User32.dll")]
    private static extern int FindWindow(String ClassName, String WindowName);

    const int SWP_NOMOVE        = 0x0002;
    const int SWP_NOSIZE        = 0x0001;            
    const int SWP_SHOWWINDOW    = 0x0040;
    const int SWP_NOACTIVATE    = 0x0010;
    [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
    public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

    public static void DoOnProcess(string processName)
    {
        var allProcs = Process.GetProcessesByName(processName);
        if (allProcs.Length > 0)
        {
            Process proc = allProcs[0];
            int hWnd = FindWindow(null, proc.MainWindowTitle.ToString());
            // Change behavior by settings the wFlags params. See http://msdn.microsoft.com/en-us/library/ms633545(VS.85).aspx
            SetWindowPos(new IntPtr(hWnd), 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
        }
    }
}

HTH

Hertzel Guinness
sumber
6
+1 ini satu-satunya jawaban yang berguna bagi saya. Saya memiliki aplikasi dengan satu master dan beberapa jendela slave mengambang. Setelah mengaktifkan semua ini, semua jendela lain juga harus dibawa ke depan. Tetapi tidak diaktifkan / mendapatkan fokus seperti jawaban kebanyakan menyarankan: itu adalah bencana karena membuat jendela saat ini diklik tidak dapat dipilih karena tiba-tiba jendela lain mendapatkan fokus.
stijn
Ada alasan untuk tidak menggunakan process.MainWindowHandle?
Sriram Sakthivel
Dalam kasus saya, saya tidak ingin jendela utama, tetapi setuju, ada cara lain untuk mendapatkan hWnd. FWIW suatu HwndSourceobjek bekerja dengan baik.
tobriand
21

Saya tahu pertanyaan ini agak lama, tetapi saya baru saja menemukan skenario yang tepat ini dan ingin berbagi solusi yang telah saya terapkan.

Seperti disebutkan dalam komentar di halaman ini, beberapa solusi yang diusulkan tidak berfungsi pada XP, yang perlu saya dukung dalam skenario saya. Sementara saya setuju dengan sentimen oleh @Matthew Xavier bahwa umumnya ini adalah praktik UX yang buruk, ada kalanya itu sepenuhnya merupakan UX yang masuk akal.

Solusi untuk membawa jendela WPF ke atas sebenarnya diberikan kepada saya oleh kode yang sama yang saya gunakan untuk menyediakan hotkey global. Artikel blog oleh Joseph Cooney berisi tautan ke contoh kode yang berisi kode asli.

Saya telah membersihkan dan memodifikasi kode sedikit, dan menerapkannya sebagai metode ekstensi untuk System.Windows.Window. Saya sudah menguji ini pada XP 32 bit dan Win7 64 bit, keduanya bekerja dengan benar.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace System.Windows
{
    public static class SystemWindows
    {
        #region Constants

        const UInt32 SWP_NOSIZE = 0x0001;
        const UInt32 SWP_NOMOVE = 0x0002;
        const UInt32 SWP_SHOWWINDOW = 0x0040;

        #endregion

        /// <summary>
        /// Activate a window from anywhere by attaching to the foreground window
        /// </summary>
        public static void GlobalActivate(this Window w)
        {
            //Get the process ID for this window's thread
            var interopHelper = new WindowInteropHelper(w);
            var thisWindowThreadId = GetWindowThreadProcessId(interopHelper.Handle, IntPtr.Zero);

            //Get the process ID for the foreground window's thread
            var currentForegroundWindow = GetForegroundWindow();
            var currentForegroundWindowThreadId = GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);

            //Attach this window's thread to the current window's thread
            AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);

            //Set the window position
            SetWindowPos(interopHelper.Handle, new IntPtr(0), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);

            //Detach this window's thread from the current window's thread
            AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);

            //Show and activate the window
            if (w.WindowState == WindowState.Minimized) w.WindowState = WindowState.Normal;
            w.Show();
            w.Activate();
        }

        #region Imports

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

        [DllImport("user32.dll")]
        private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

        [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        #endregion
    }
}

Saya harap kode ini membantu orang lain yang mengalami masalah ini.

Zodman
sumber
Hei, lihat di sana! Saya telah berjuang dengan ini selama berbulan-bulan! Ini berfungsi untuk kedua situasi saya. Luar biasa! (Windows 7 x64)
mdiehl13
Sebenarnya, sepertinya hanya berfungsi jika saya melakukan ini: App.mainWindow.Show (); SystemWindows.GlobalActivate (App.mainwindow); // Ketika saya menghapus .show () pertama tidak membawa ke depan
mdiehl13
+1 untuk SetWindowPos (), saya sedang mencari cara untuk hanya membawa Window saya ke depan tanpa mengganggu aplikasi lain atau mencuri fokus. this.Activate () mencuri fokus.
prettyvoid
Ini melakukannya untuk saya, dan kasus saya intinya adalah mencuri fokus, karena itu terjadi ketika pengguna berinteraksi dengan elemen tertentu. jadi Terima kasih banyak ini tampaknya bekerja konsisten! menelepon this.Activate()saja sepertinya berfungsi beberapa kali.
Peter
13

Jika pengguna berinteraksi dengan aplikasi lain, Anda mungkin tidak dapat membawanya ke depan. Sebagai aturan umum, suatu proses hanya bisa berharap untuk mengatur jendela latar depan jika proses itu sudah proses latar depan. (Microsoft mendokumentasikan pembatasan dalam entri MSDN SetForegroundWindow () .) Ini karena:

  1. Pengguna "memiliki" latar depan. Misalnya, akan sangat menjengkelkan jika program lain mencuri latar depan saat pengguna mengetik, paling tidak mengganggu alur kerjanya, dan mungkin menyebabkan konsekuensi yang tidak diinginkan karena penekanan tombol yang dimaksudkan untuk satu aplikasi salah ditafsirkan oleh pelaku sampai dia melihat perubahan. .
  2. Bayangkan bahwa masing-masing dari dua program memeriksa untuk melihat apakah jendelanya adalah latar depan dan mencoba untuk mengaturnya ke latar depan jika tidak. Segera setelah program kedua berjalan, komputer dianggap tidak berguna karena latar depan memantul di antara keduanya di setiap peralihan tugas.
Matthew Xavier
sumber
Poin bagus. Namun, tujuan kode ini bersamaan dengan hotkey global, dan aplikasi lain melakukannya.
Factor Mystic
Harus menggunakan PInvoke di C # untuk meniru apa yang dijelaskan dalam artikel ini, codeproject.com/Tips/76427/…
Lex Li
lalu mengapa ekspresi kesalahan dialog popup tetap terlihat ketika saya beralih ke visual studio kadang-kadang? : - /
Simon_Weaver
Simon, saya menduga popup kesalahan yang Anda lihat adalah jendela "paling atas" (keputusan desain yang saya tidak setujui). Ada perbedaan antara jendela latar depan (yang menerima input pengguna) dan jendela "paling atas" dalam Z-order. Jendela apa pun dapat membuatnya sendiri "paling atas", yang menempatkannya di atas semua jendela yang tidak paling atas, tetapi tidak memberikan fokus papan ketik jendela, dll. Seperti yang dilakukan jendela latar depan.
Matius Xavier
Caranya gagal untuk beberapa jendela khusus. Visual Studio dan jendela prompt perintah harus memiliki sesuatu yang mencegah jendela lain menjadi jendela latar depan.
Lex Li
9

Saya tahu bahwa ini adalah jawaban yang terlambat, mungkin bermanfaat bagi para peneliti

 if (!WindowName.IsVisible)
 {
     WindowName.Show();
     WindowName.Activate();
 }
Jamaxack
sumber
9

Mengapa beberapa jawaban di halaman ini salah!

  • Setiap jawaban yang digunakan window.Focus()salah.

    • Mengapa? Jika pesan pemberitahuan muncul, window.Focus()akan mengambil fokus dari apa pun yang diketik pengguna saat itu. Ini sangat membuat frustasi bagi pengguna akhir, terutama jika popup muncul cukup sering.
  • Setiap jawaban yang digunakan window.Activate()salah.

    • Mengapa? Ini akan membuat semua jendela induk terlihat juga.
  • Setiap jawaban yang dihilangkan window.ShowActivated = falsesalah.
    • Mengapa? Ini akan mengambil fokus dari jendela lain ketika pesan muncul yang sangat menjengkelkan!
  • Setiap jawaban yang tidak digunakan Visibility.Visible untuk menyembunyikan / menampilkan jendela salah.
    • Mengapa? Jika kita menggunakan Citrix, jika jendela tidak runtuh ketika ditutup, itu akan meninggalkan penangguhan persegi panjang hitam yang aneh di layar. Jadi, kita tidak bisa menggunakan window.Show()dan window.Hide().

Pada dasarnya:

  • Jendela tidak boleh mengambil fokus dari jendela lain saat diaktifkan;
  • Jendela tidak boleh mengaktifkan induknya ketika ditampilkan;
  • Jendela tersebut harus kompatibel dengan Citrix.

Solusi MVVM

Kode ini 100% kompatibel dengan Citrix (tidak ada area kosong pada layar). Ini diuji dengan WPF dan DevExpress normal.

Jawaban ini ditujukan untuk setiap kasus penggunaan di mana kami ingin jendela pemberitahuan kecil yang selalu di depan jendela lain (jika pengguna memilih ini dalam preferensi).

Jika jawaban ini tampaknya lebih kompleks daripada yang lain, itu karena kuat, kode tingkat perusahaan. Beberapa jawaban lain di halaman ini sederhana, tetapi tidak benar-benar berfungsi.

XAML - Properti Terlampir

Tambahkan properti terlampir ini ke UserControldalam jendela. Properti terlampir akan:

  • Tunggu hingga Loadedacara diaktifkan (jika tidak, tidak dapat melihat pohon visual untuk menemukan jendela induk).
  • Tambahkan pengendali acara yang memastikan bahwa jendela terlihat atau tidak.

Kapan saja, Anda dapat mengatur jendela berada di depan atau tidak, dengan membalik nilai properti terlampir.

<UserControl x:Class="..."
         ...
         attachedProperties:EnsureWindowInForeground.EnsureWindowInForeground=
             "{Binding EnsureWindowInForeground, Mode=OneWay}">

C # - Metode Penolong

public static class HideAndShowWindowHelper
{
    /// <summary>
    ///     Intent: Ensure that small notification window is on top of other windows.
    /// </summary>
    /// <param name="window"></param>
    public static void ShiftWindowIntoForeground(Window window)
    {
        try
        {
            // Prevent the window from grabbing focus away from other windows the first time is created.
            window.ShowActivated = false;

            // Do not use .Show() and .Hide() - not compatible with Citrix!
            if (window.Visibility != Visibility.Visible)
            {
                window.Visibility = Visibility.Visible;
            }

            // We can't allow the window to be maximized, as there is no de-maximize button!
            if (window.WindowState == WindowState.Maximized)
            {
                window.WindowState = WindowState.Normal;
            }

            window.Topmost = true;
        }
        catch (Exception)
        {
            // Gulp. Avoids "Cannot set visibility while window is closing".
        }
    }

    /// <summary>
    ///     Intent: Ensure that small notification window can be hidden by other windows.
    /// </summary>
    /// <param name="window"></param>
    public static void ShiftWindowIntoBackground(Window window)
    {
        try
        {
            // Prevent the window from grabbing focus away from other windows the first time is created.
            window.ShowActivated = false;

            // Do not use .Show() and .Hide() - not compatible with Citrix!
            if (window.Visibility != Visibility.Collapsed)
            {
                window.Visibility = Visibility.Collapsed;
            }

            // We can't allow the window to be maximized, as there is no de-maximize button!
            if (window.WindowState == WindowState.Maximized)
            {
                window.WindowState = WindowState.Normal;
            }

            window.Topmost = false;
        }
        catch (Exception)
        {
            // Gulp. Avoids "Cannot set visibility while window is closing".
        }
    }
}

Pemakaian

Untuk menggunakan ini, Anda perlu membuat jendela di ViewModel Anda:

private ToastView _toastViewWindow;
private void ShowWindow()
{
    if (_toastViewWindow == null)
    {
        _toastViewWindow = new ToastView();
        _dialogService.Show<ToastView>(this, this, _toastViewWindow, true);
    }
    ShiftWindowOntoScreenHelper.ShiftWindowOntoScreen(_toastViewWindow);
    HideAndShowWindowHelper.ShiftWindowIntoForeground(_toastViewWindow);
}

private void HideWindow()
{
    if (_toastViewWindow != null)
    {
        HideAndShowWindowHelper.ShiftWindowIntoBackground(_toastViewWindow);
    }
}

Tautan tambahan

Untuk kiat tentang cara memastikan bahwa jendela pemberitahuan selalu bergeser kembali ke layar yang terlihat, lihat jawaban saya: Di WPF, bagaimana cara menggeser jendela ke layar jika tidak dimatikan? .

Contango
sumber
5
"Kode tingkat perusahaan" dan beberapa baris kemudian catch (Exception) { }. Ya benar ... Dan itu menggunakan kode yang bahkan tidak ditampilkan dalam jawaban seperti _dialogServiceatau ShiftWindowOntoScreenHelper. Plus meminta untuk membuat jendela di sisi viewmodel (yang pada dasarnya memecah seluruh pola MVVM) ...
Kryptos
@Kryptos Ini adalah kode tingkat perusahaan. Saya mengetiknya dari memori, dan teknik yang tepat ini digunakan di perusahaan FTSE100 besar. Kehidupan nyata agak kurang murni dibandingkan dengan pola desain sempurna yang kita semua bertujuan.
Contango
Saya tidak suka fakta bahwa kita menyimpan contoh jendela dalam model tampilan sendiri, seperti yang disebutkan Kryptos yang merusak seluruh titik mvvm, mungkin itu bisa dilakukan dalam codebehind saja?
Igor Meszaros
1
@Igor Meszaros Setuju. Sekarang saya memiliki lebih banyak pengalaman, jika saya harus melakukannya lagi, itu saya akan menambahkan Perilaku, dan mengendalikannya menggunakan Func<>yang terikat ke ViewModel.
Contango
7

Saya memiliki masalah serupa dengan aplikasi WPF yang dipanggil dari aplikasi Access melalui objek Shell.

Solusi saya di bawah ini - berfungsi di XP dan Win7 x64 dengan aplikasi dikompilasi untuk target x86.

Saya lebih suka melakukan ini daripada mensimulasikan tab-alt.

void Window_Loaded(object sender, RoutedEventArgs e)
{
    // make sure the window is normal or maximised
    // this was the core of the problem for me;
    // even though the default was "Normal", starting it via shell minimised it
    this.WindowState = WindowState.Normal;

    // only required for some scenarios
    this.Activate();
}
Seth
sumber
4

Ya, karena ini adalah topik yang panas ... inilah yang bekerja untuk saya. Saya mendapat kesalahan jika saya tidak melakukannya karena Activate () akan kesalahan pada Anda jika Anda tidak dapat melihat jendela.

Xaml:

<Window .... 
        Topmost="True" 
        .... 
        ContentRendered="mainWindow_ContentRendered"> .... </Window>

Codebehind:

private void mainWindow_ContentRendered(object sender, EventArgs e)
{
    this.Topmost = false;
    this.Activate();
    _UsernameTextBox.Focus();
}

Ini adalah satu-satunya cara bagi saya untuk mendapatkan jendela untuk ditampilkan di atas. Kemudian aktifkan sehingga Anda bisa mengetik di dalam kotak tanpa harus menetapkan fokus dengan mouse. control.Focus () tidak akan berfungsi kecuali jendela aktif ();

Omzig
sumber
2

Yah saya menemukan pekerjaan di sekitar. Saya melakukan panggilan dari pengait keyboard yang digunakan untuk mengimplementasikan hotkey. Panggilan berfungsi seperti yang diharapkan jika saya memasukkannya ke BackgroundWorker dengan jeda. Itu adalah kludge, tetapi saya tidak tahu mengapa itu tidak berhasil pada awalnya.

void hotkey_execute()
{
    IntPtr handle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(delegate
        {
            Thread.Sleep(10);
            SwitchToThisWindow(handle, true);
        });
    bg.RunWorkerAsync();
}
Faktor Mystic
sumber
Hanya tertarik: Apakah Anda mencoba Window.Activate (seperti yang disarankan oleh Morten) dan saran lainnya? Mereka tampaknya kurang hacky dari kludge yang diakui ini.
Simon D.
Ini sudah cukup lama, tapi ya, pada saat saya mencobanya
Factor Mystic
Ini tidak berfungsi pada Windows XP saya. Saya merekomendasikan jawaban @Matthew Xavier.
Lex Li
2

Untuk menampilkan jendela APA SAJA yang dibuka, impor DLL tersebut:

public partial class Form1 : Form
{
    [DllImportAttribute("User32.dll")]
    private static extern int FindWindow(String ClassName, String WindowName);
    [DllImportAttribute("User32.dll")]
    private static extern int SetForegroundWindow(int hWnd);

dan dalam program Kami mencari aplikasi dengan judul yang ditentukan (tulis judul tanpa huruf pertama (indeks> 0))

  foreach (Process proc in Process.GetProcesses())
                {
                    tx = proc.MainWindowTitle.ToString();
                    if (tx.IndexOf("Title of Your app WITHOUT FIRST LETTER") > 0)
                    {
                        tx = proc.MainWindowTitle;
                        hWnd = proc.Handle.ToInt32(); break;
                    }
                }
                hWnd = FindWindow(null, tx);
                if (hWnd > 0)
                {
                    SetForegroundWindow(hWnd);
                }
rahmud
sumber
"Judul aplikasi Anda TANPA SURAT PERTAMA" Oof, hacky hacky hacky. Mengapa tidak menggunakannya IndexOfdengan benar?
Lightness Races in Orbit
1

Masalahnya mungkin bahwa utas yang memanggil kode Anda dari hook belum diinisialisasi oleh runtime sehingga memanggil metode runtime tidak berfungsi.

Mungkin Anda bisa mencoba melakukan Invoke untuk menyusun kode Anda ke utas UI untuk memanggil kode Anda yang membawa jendela ke latar depan.

Joshperry
sumber
1

Kode-kode ini akan berfungsi dengan baik setiap saat.

Pertama-tama atur event handler yang diaktifkan di XAML:

Activated="Window_Activated"

Tambahkan baris di bawah ini ke blok konstruktor Jendela Utama Anda:

public MainWindow()
{
    InitializeComponent();
    this.LocationChanged += (sender, e) => this.Window_Activated(sender, e);
}

Dan di dalam event handler yang diaktifkan salin kode ini:

private void Window_Activated(object sender, EventArgs e)
{
    if (Application.Current.Windows.Count > 1)
    {
        foreach (Window win in Application.Current.Windows)
            try
            {
                if (!win.Equals(this))
                {
                    if (!win.IsVisible)
                    {
                        win.ShowDialog();
                    }

                    if (win.WindowState == WindowState.Minimized)
                    {
                        win.WindowState = WindowState.Normal;
                    }

                    win.Activate();
                    win.Topmost = true;
                    win.Topmost = false;
                    win.Focus();
                }
            }
            catch { }
    }
    else
        this.Focus();
}

Langkah-langkah ini akan bekerja dengan baik dan akan membawa ke depan semua jendela lain ke jendela orang tua mereka.

Matriks
sumber
0

Jika Anda mencoba untuk menyembunyikan jendela, misalnya Anda meminimalkan jendela, saya menemukan menggunakan itu

    this.Hide();

akan menyembunyikannya dengan benar, lalu cukup menggunakan

    this.Show();

kemudian akan menampilkan jendela sebagai item paling top sekali lagi.

Chris
sumber
0

Hanya ingin menambahkan solusi lain untuk pertanyaan ini. Implementasi ini berfungsi untuk skenario saya, di mana CaliBurn bertanggung jawab untuk menampilkan Window utama.

protected override void OnStartup(object sender, StartupEventArgs e)
{
    DisplayRootViewFor<IMainWindowViewModel>();

    Application.MainWindow.Topmost = true;
    Application.MainWindow.Activate();
    Application.MainWindow.Activated += OnMainWindowActivated;
}

private static void OnMainWindowActivated(object sender, EventArgs e)
{
    var window = sender as Window;
    if (window != null)
    {
        window.Activated -= OnMainWindowActivated;
        window.Topmost = false;
        window.Focus();
    }
}
d.moncada
sumber
0

Ingatlah untuk tidak memasukkan kode yang menunjukkan jendela itu di dalam handel PreviewMouseDoubleClick karena jendela yang aktif akan kembali ke jendela yang menangani acara tersebut. Cukup letakkan di event handler MouseDoubleClick atau berhenti menggelegak dengan mengatur e. Ditangani ke True.

Dalam kasus saya, saya menangani PreviewMouseDoubleClick pada Listview dan tidak mengatur e.Handled = true lalu mengangkat acara penyihir MouseDoubleClick fokus kembali ke jendela asli.

Michel P.
sumber
-1

Saya membangun metode ekstensi agar mudah digunakan kembali.

using System.Windows.Forms;
    namespace YourNamespace{
        public static class WindowsFormExtensions {
            public static void PutOnTop(this Form form) {
                form.Show();
                form.Activate();
            }// END PutOnTop()       
        }// END class
    }// END namespace

Panggil di Form Constructor

namespace YourNamespace{
       public partial class FormName : Form {
       public FormName(){
            this.PutOnTop();
            InitalizeComponents();
        }// END Constructor
    } // END Form            
}// END namespace
Mike
sumber
Hai Mike. Anda menjawab pertanyaan ini agak terlambat. Dapatkah Anda menjelaskan dalam jawaban Anda mengapa pendekatan ini berbeda (dan mungkin lebih baik) dari jawaban yang sangat baik yang sudah diposting untuk pertanyaan ini?
Noel Widmer
Hanya terlambat karena saya hanya perlu melakukan ini, dan saya menemukan ini dan ingin berbagi bagaimana saya memecahkan masalah membungkus orang lain ingin menggunakannya.
Mike
Tentu, saya dipilih untuk meninjau posting Anda dan ingin membuat Anda sadar. Itu selalu baik untuk memberikan jawaban baru jika Anda pikir itu merupakan kontribusi yang baik kepada masyarakat.
Noel Widmer
2
Pertanyaan ini khusus tentang WPF, tetapi solusi Anda adalah untuk WinForms.
Brian Reichle