WPF'de bir pencere öne getirin


214

WPF uygulamamı masaüstünün önüne nasıl getirebilirim? Şimdiye kadar denedim:

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

Bunların hiçbiri işi yapmıyor ( Marshal.GetLastWin32Error()bu işlemlerin başarıyla tamamlandığını ve her tanım için P / Invoke özniteliklerinin sahip olduğunu söylüyor SetLastError=true).

Yeni bir boş WPF uygulaması oluşturur ve SwitchToThisWindowbir zamanlayıcı ile ararsam, tam olarak beklendiği gibi çalışır, bu yüzden orijinal durumumda neden çalışmadığından emin değilim.

Düzenleme : Bunu küresel bir kısayol tuşu ile birlikte yapıyorum.


MainWindow'un istediğiniz pencere olduğunu doğruladınız mı? MSDN'den: MainWindow, AppDomain'de başlatılacak ilk Window nesnesine bir başvuru ile otomatik olarak ayarlanır.
Todd White

İyi düşünülmüş, ancak uygulamadaki tek Pencere.
Factor Mystic

Biraz daha bağlam kodu verebilir misiniz?
Todd White

Yanıtlar:


314
myWindow.Activate();

Pencereyi ön plana getirmeye çalışır ve etkinleştirir.

Yanlış anlamadıysam ve Her Zaman Üstte davranmak istemezsen bu hile yapmalı. Bu durumda istediğiniz:

myWindow.TopMost = true;

14
Sadece myWindow.Show () kullanıyordum ve bazen üstte değildi. Hemen ardından myWindow.Activate () öğesine bir çağrı yaptım ve işe yaradı.
Bermo

4
Etkinleştirme bazen Windows XP'de çalışmaz. @Matthew Xavier'in cevabını öneriyorum.
Lex Li

ShowActivated varsayılan olarak açık olduğu için biraz garip.
greenoldman

1
İlk cevap güzel, bunun için teşekkürler! Ancak, Topmostdiğer açılır pencereleri gizleyebileceği ve beklenmedik davranışlara sahip olabileceğinden , özelliği kullanan ikinci kod satırı kötü bir uygulamadır.
Jonathan Perry

3
Aslında bununla yapılabilir: if (myWindow.WindowState == WindowState.Minimized) myWindow.WindowState = WindowState.Normal;Garip bir şekilde, herhangi bir Maximized penceresini koruyacak ve onları Normal bir duruma geri döndürmeyecektir.
r41n

168

Pencereyi en üste getiren bir çözüm buldum, ancak normal bir pencere gibi davranıyor:

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

1
Harika bir ipucu! TopMost, pencere zaten açıksa, ancak diğer pencerelerin altındaysa sihri Windows 7'de gerçekleştirir.
gsb

Bu benim için hile yaptı. TopMost'un garip bir kullanımı gibi görünen ek yorum için gsb'ye teşekkürler!
Jen

1
Teşekkürler - düzeltme kısa ve tatlıydı.
code4life

2
Benim durumumda Window.Activate () ve Window.Focus () yeterliydi. Ayar Penceresi: TopMost gerekli değildir.
virious

6
Kullanmayın Window.Focus(). Bu, odağı kullanıcının şu anda bir metin kutusuna yazdıklarından uzaklaştıracak ve bu da son kullanıcılar için çılgınca sinir bozucu olacaktır. Yukarıdaki kod onsuz iyi çalışıyor.
Contango

32

Pencerenin ilk yüklendiğinde ön tarafta olması gerekiyorsa, aşağıdakileri kullanmalısınız:

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

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

1
C # 'da Launchy ( launchy.net )' e benzer bir şey geliştirirseniz , bu cevabın neredeyse işe yaramaz olduğunu fark etmelisiniz.
Lex Li

21

Bunu hızlı bir kopyala yapıştır yapmak için - İşlem
sınıfı DoOnProcessana penceresini ön plana taşımak için bu sınıfı ' yöntemi kullanın (ancak diğer pencerelerden odağı çalmamak için)

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


6
+1 bu benim için yararlı olan tek cevap. Bir master ve birkaç kayan köle pencere ile bir uygulama var. Bunlardan herhangi birini etkinleştirdikten sonra, diğer tüm pencereler de öne getirilmelidir. Ancak çoğu yanıtın önerdiği gibi aktif değil / odak kazanın: aniden başka bir pencere odak kazandığından, şu anda tıklanan pencerenin tıklanamaz olmasını sağladığı için bu bir felakettir.
stijn

Kullanmamanız için herhangi bir neden var process.MainWindowHandlemı?
Sriram Sakthivel

Benim durumumda, ana pencereyi istemedim, ancak kabul ettim, bir başka yol almanın yolları var hWnd. FWIW bir HwndSourcenesne iyi çalıştı.
tobriand

21

Bu sorunun oldukça eski olduğunu biliyorum, ama bu kesin senaryoya yeni geldim ve uyguladığım çözümü paylaşmak istedim.

Bu sayfadaki yorumlarda belirtildiği gibi, önerilen çözümlerin birçoğu senaryomda desteklemem gereken XP'de çalışmıyor. @Matthew Xavier'in genel olarak bunun kötü bir UX uygulaması olduğu fikrine katılırken, bunun tamamen makul bir UX olduğu zamanlar var.

Üstüne bir WPF penceresi getirmek için çözüm aslında bana küresel kısayol tuşu sağlamak için kullandığım aynı kod tarafından sağlandı. Joseph Cooney'nin bir blog makalesi , orijinal kodu içeren kod örneklerine bir bağlantı içerir.

Kodu biraz temizledim ve değiştirdim ve System.Windows.Window'a bir uzantı yöntemi olarak uyguladım. Bunu XP 32 bit ve Win7 64 bit üzerinde test ettim, ikisi de doğru çalışıyor.

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
    }
}

Umarım bu kod bu sorunla karşılaşanlara yardımcı olur.


Hey lookie orada! Aylardır bununla mücadele ediyorum! Bu her iki durumum için de geçerli. Müthiş! (Windows 7 x64)
mdiehl13 10:15

Aslında, sadece bunu yaparsam işe yarıyor gibi görünüyor: App.mainWindow.Show (); SystemWindows.GlobalActivate (App.mainwindow); // İlk .show () 'ı kaldırdığımda öne getirmiyor
mdiehl13

SetWindowPos () için +1, diğer uygulamaları kesintiye uğratmadan veya odak çalmadan sadece Penceremi öne getirmenin bir yolunu arıyordum. Activate () odağı çalar.
prettyvoid

Bu benim için yaptı ve benim durumum tüm mesele, bir kullanıcı belirli bir elementle etkileşime girdiğinde olduğu gibi odağı çalmaktı. çok teşekkürler bu tutarlı çalışıyor gibi görünüyor! sadece aramak this.Activate()sadece birkaç kez işe yarıyor gibi görünüyor.
Peter

13

Kullanıcı başka bir uygulama ile etkileşime giriyorsa, kendinizinkini öne getirmek mümkün olmayabilir. Genel bir kural olarak, bir işlem yalnızca bu işlem zaten ön plan işlemi ise ön plan penceresinin ayarlanmasını bekleyebilir. (Microsoft, SetForegroundWindow () MSDN girişindeki kısıtlamaları belgelemektedir .) Bunun nedeni:

  1. Kullanıcı ön plana "sahiptir". Örneğin, kullanıcı yazarken, en azından iş akışını keserken başka bir programın ön planını çalması ve muhtemelen bir uygulama için klavyedeki tuş vuruşları değişikliği fark edene kadar yanlış sonuçlara yol açması nedeniyle istenmeyen sonuçlara neden olması son derece can sıkıcı olurdu. .
  2. İki programın her birinin penceresinin ön plan olup olmadığını kontrol ettiğini ve eğer değilse ön plana ayarlamaya çalıştığını düşünün. İkinci program çalışır çalışmaz, her görev anahtarında ön plan ikisi arasında sıçrarken bilgisayar işe yaramaz hale gelir.

İyi bir nokta. Kodun amacı genel bir kısayol tuşuyla bağlantılıydı ve diğer uygulamalar bunu bir şekilde yapıyor.
Faktör Mistik

Bu makalede anlatılanları taklit etmek için C # içinde PInvoke kullanmanız gerekir, codeproject.com/Tips/76427/…
Lex Li

neden bazen görsel stüdyoya geçtiğimde ifade karışımları hata açılır pencereleri görünür kalıyor? : - /
Simon_Weaver

Simon, gördüğünüz hata açılır pencerelerinin "en üst" pencereler (onaylamamış olduğum bir tasarım kararı) olduğundan şüpheleniyorum. Ön plan penceresi (kullanıcı girişini alan) ve Z-düzeninde bir "en üstteki" pencere arasında bir fark vardır. Herhangi bir pencere kendini "en üstte" yapabilir, bu da onu en üstteki olmayan pencerelerin üstüne yerleştirir, ancak pencere klavyesi odağını vb. Ön plan penceresine dönüşme biçimini vermez.
Matthew Xavier

Hile birkaç özel pencere için başarısız olur. Visual Studio ve komut istemi pencerelerinde, diğer pencerelerin ön plan penceresine dönüşmesini engelleyen bir şey olmalıdır.
Lex Li

9

Bunun geç cevap olduğunu biliyorum, belki araştırmacılar için yararlı olabilir

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

9

Bu sayfadaki cevapların bazıları neden yanlış!

  • Kullanan herhangi bir cevap window.Focus()yanlıştır.

    • Neden? Bir bildirim mesajı açılırsa window.Focus(), odağı kullanıcının o anda yazdığı her şeyden uzaklaştıracaktır. Bu, özellikle pop-up'ların oldukça sık meydana gelmesi durumunda son kullanıcılar için delicesine sinir bozucu.
  • Kullanan herhangi bir cevap window.Activate()yanlıştır.

    • Neden? Herhangi bir üst pencereyi de görünür hale getirecektir.
  • Atlayan herhangi bir cevap window.ShowActivated = falseyanlıştır.
    • Neden? Mesaj açıldığında odağı başka bir pencereden uzak tutacak ki bu çok sinir bozucu!
  • Visibility.VisiblePencereyi gizlemek / göstermek için kullanılmayan yanıtlar yanlıştır.
    • Neden? Citrix kullanıyorsak, pencere kapatıldığında daraltılmazsa, ekranda tuhaf bir siyah dikdörtgen tutacak. Böylece window.Show()ve kullanamayız window.Hide().

esasen:

  • Pencere, etkinleştirildiğinde odağı başka bir pencereden uzak tutmamalıdır;
  • Pencere gösterildiğinde üst öğesini etkinleştirmemelidir;
  • Pencere Citrix ile uyumlu olmalıdır.

MVVM Çözümü

Bu kod Citrix ile% 100 uyumludur (ekranın boş alanı yoktur). Hem normal WPF hem de DevExpress ile test edilmiştir.

Bu yanıt, her zaman diğer pencerelerin önünde küçük bir bildirim penceresi istediğimiz herhangi bir kullanım durumu için tasarlanmıştır (kullanıcı bunu tercihlerde seçerse).

Bu yanıt diğerlerinden daha karmaşık görünüyorsa, bunun nedeni sağlam, kurumsal düzeyde kod olmasıdır. Bu sayfadaki diğer cevapların bazıları basittir, ancak aslında çalışmaz.

XAML - Ekli Özellik

Bu eklenen özelliği UserControlpencerenin içindeki herhangi bir yere ekleyin . Ekli özellik:

  • LoadedEtkinlik tetiklenene kadar bekleyin (aksi takdirde üst pencereyi bulmak için görsel ağacı arayamaz).
  • Pencerenin görünür olmasını veya görünmemesini sağlayan bir olay işleyicisi ekleyin.

Herhangi bir noktada, attached özelliğinin değerini çevirerek pencereyi önde olacak ya da olmayacak şekilde ayarlayabilirsiniz.

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

Yardımcı Yöntem

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".
        }
    }
}

kullanım

Bunu kullanmak için ViewModel'inizde bir pencere oluşturmanız gerekir:

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

Ek bağlantılar

Bir bildirim penceresinin her zaman görünür ekrana nasıl geri döndüğünden nasıl emin olacağınıza dair ipuçları için cevabım bakın: WPF'de, bir pencere ekran dışındaysa ekrana nasıl kaydırılır? .


5
"Kurumsal seviye kodu" ve birkaç satır sonra catch (Exception) { }. Evet doğru ... Ve cevabında bile gösterilmeyen kodu kullanır _dialogServiceya da ShiftWindowOntoScreenHelper. Artı (temelde tüm MVVM desenini kıran) viewmodel tarafında pencere oluşturmak istiyoruz ...
Kryptos

@Kryptos Bu, kurumsal düzey kodudur. Bunu bellekten yazdım ve bu kesin teknik büyük bir FTSE100 şirketinde kullanılıyor. Gerçek hayat, hepimizin amaçladığı mükemmel tasarım desenlerine kıyasla biraz daha az bozulmuştur.
Contango

Kryptos'un mvvm'nin tüm noktasını kırdığından bahsettiği gibi, pencerenin bir örneğini kendim tutmamız gerçeğinden hoşlanmıyorum, belki bunun yerine kod arkasında yapılabilirdi?
Igor Meszaros

1
@Igor Meszaros Kabul etti. Şimdi daha fazla deneyime sahip olduğum için, tekrar yapmak zorunda kalsaydım, bir Davranış ekler Func<>ve ViewModel'e bağlı bir kullanarak kontrol ederdim .
Contango

7

Shell nesnesi aracılığıyla bir Access uygulamasından çağrılan bir WPF uygulaması ile benzer bir sorun yaşadım.

Benim çözümüm aşağıda - XP ve Win7 x64'te çalışıyor ve uygulama x86 hedefine derlendi.

Bunu alt sekmeyi simüle etmekten çok yapmayı tercih ederim.

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

4

Bu çok sıcak bir konu olduğu için ... işte benim için işe yarar. Bu şekilde yapmadıysam hatalar aldım çünkü pencereyi göremiyorsanız Activate () size hata verecektir.

Xaml:

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

codeBehind:

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

Pencerenin üstte görünmesini sağlamanın tek yolu buydu. Ardından etkinleştirin, böylece fareyle odağı ayarlamak zorunda kalmadan kutuya yazabilirsiniz. control.Focus (), pencere Active () olmadığı sürece çalışmaz;


2

Etrafında bir iş buldum. Bir kısayol tuşu uygulamak için kullanılan bir klavye kancasından arama yapıyorum. Duraklama ile bir BackgroundWorker içine koymak eğer çağrı beklendiği gibi çalışır. Bu bir çamur, ama neden orijinal olarak çalışmadığını bilmiyorum.

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

Sadece ilgilendi: Window.Activate'i (Morten tarafından önerildiği gibi) ve diğer önerileri denediniz mi? Bu kabul edilen çamurdan daha az acayip görünüyorlar.
Simon D.

Bu oldukça önce oldu, ama evet, ben denedim o zaman
Factor Mystic

Bu, Windows XP'de çalışmıyor. @Matthew Xavier'in cevabını öneriyorum.
Lex Li

2

Şu anda açık olan herhangi bir pencereyi göstermek için bu DLL dosyasını içe aktarın:

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

ve programda Belirtilen başlıklı uygulamayı ararız (ilk harf olmadan başlık yaz (dizin> 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);
                }

"İLK MEKTUP OLMADAN" Uygulamanızın Başlığı " Oof, hacky hacky hacky. IndexOfBunun yerine neden doğru kullanmıyorsunuz ?
Yörüngedeki Hafiflik Yarışları

1

Sorun kancadan kodunuzu çağıran iş parçacığı çalışma zamanı tarafından başlatılmamış olabilir, bu nedenle arama zamanı yöntemleri çalışmaz.

Belki de pencereyi ön plana getiren kodunuzu çağırmak için kodunuzu UI iş parçacığına marshal etmek için bir Invoke yapmayı deneyebilirsiniz.


1

Bu kodlar her zaman iyi çalışır.

İlk önce XAML'de etkin olay işleyiciyi ayarlayın:

Activated="Window_Activated"

Ana Pencere yapıcı bloğunuza aşağıdaki satırı ekleyin:

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

Etkinleştirilen olay işleyicisinin içinde şu kodları kopyalayın:

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

Bu adımlar iyi çalışır ve diğer tüm pencereleri ebeveyn penceresine getirecektir.


0

Pencereyi gizlemeye çalışıyorsanız, örneğin pencereyi simge durumuna küçültüyorsanız,

    this.Hide();

doğru şekilde gizleyecek, daha sonra

    this.Show();

sonra pencereyi bir kez daha en üstteki öğe olarak gösterecektir.


0

Sadece bu soruya başka bir çözüm eklemek istedim. Bu uygulama, CaliBurn'un ana Pencereyi görüntülemekle sorumlu olduğu senaryom için çalışır.

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

0

Etkin pencere olayı işleyen pencereye geri döneceğinden, bu pencereyi gösteren kodu bir PreviewMouseDoubleClick işleyicisine koymamayı unutmayın. Sadece MouseDoubleClick olay işleyicisine koyun veya e.Handled öğesini True olarak ayarlayarak köpürmeyi bırakın.

Benim durumumda bir Listview PreviewMouseDoubleClick idare ediyordu ve e.Handled = true ayarlanmadı sonra MouseDoubleClick olay cadı odak orijinal penceresine geri odak yükseltti.


-1

Kolayca yeniden kullanmak için bir uzatma yöntemi oluşturdum.

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

Form Oluşturucuyu Çağırın

namespace YourNamespace{
       public partial class FormName : Form {
       public FormName(){
            this.PutOnTop();
            InitalizeComponents();
        }// END Constructor
    } // END Form            
}// END namespace

Merhaba Mike. Bu soruyu oldukça geç cevaplıyorsunuz. Cevabınızda bu yaklaşımın neden bu soru için gönderilmiş olan çok iyi cevaplardan farklı (ve belki de daha iyi) olduğunu açıklayabilir misiniz?
Noel Widmer

Sadece bunu yapmam gerektiğinde geç kaldım ve bununla karşılaştım ve sorunu nasıl çözdüğümü paylaşmak istedim.
Mike

Elbette, yazınızı gözden geçirmeyi seçtim ve sizi bilgilendirmek istedim. Topluluğa iyi bir katkı olduğunu düşünüyorsanız yeni bir yanıt vermek her zaman iyidir.
Noel Widmer

2
Bu soru özellikle WPF ile ilgiliydi, ancak çözümünüz WinForms için.
Brian Reichle
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.