2009-09-23 1 views
25

Я пишу приложение Windows Forms в C#. Мне нужно уметь вывести его на передний план. После некоторого Googling и экспериментов у меня есть рабочее решение, которое выглядит довольно взломанным.Что такое «правильный» способ принести приложение Windows Forms на передний план?

Я хотел бы знать элегантный способ сделать это, если таковой имеется. Мне нужно приложение для восстановления и выходить на передний план, было ли оно сведено к минимуму или не сведено к минимуму, а в фоновом режиме.

Текущий код выглядит следующим образом:

WindowState = FormWindowState.Minimized; 
WindowState = FormWindowState.Normal; 
BringToFront(); 
Focus(); 
+3

с аудио запись Emeril Lagasse! BAM! –

+1

Хорошо, после некоторого Googling, я думаю, что это смешно. – RedFilter

+2

Я обычно ненавижу людей, которые говорят такие вещи, но серьезно, пожалуйста, не делайте так, чтобы ваше приложение делало это, если у вас нет никакого мнения в этом вопросе. Приложения, которые украдут фокус, должны считаться вредными. – Coxy

ответ

40

Вы пробовали Form.Activate?

Этот код, кажется, что вы хотите, путем восстановления формы нормального размера, если свести к минимуму, а затем активируя его, чтобы установить фокус:

if (this.WindowState == FormWindowState.Minimized) 
{ 
    this.WindowState = FormWindowState.Normal; 
} 

this.Activate(); 

Внимание: это раздражает! Если это просто приложение для вашего личного использования, как вы говорите, возможно, вы сможете жить с ним. :)

+1

Я просто попробовал это. Активировать() не будет работать, если форма является дочерней формой MDI, и пользователь работает с другим приложением. –

+4

Также полезно, если вы сворачиваете в системный лоток и должны активироваться и перемещаться вперед по щелчку, когда окно уже находится в нормальном состоянии. –

+0

Я также нашел [this] (http://stackoverflow.com/questions/4410717/c-sharp-programmatically-unminimize-form), полезный для восстановления формы до ее предыдущего состояния (обычного или максимизированного). – Giles

4

Вы можете установить .TopMost в true, позвонить DoEvents(), а затем установить .TopMost обратно на false. Он все еще хакерский, но если «Активировать» и «Показать» не работают, это лучше, чем минимизация/повторное показ.

+0

Это не работает для меня, по крайней мере, не в среде отладки хоста Visual Studio. – RedFilter

+0

DoEvents может привести к разного рода гадости - я бы настоятельно советовал не использовать его. –

+0

@JonCage Определенно согласен: http://stackoverflow.com/questions/11352301/how-to-use-doevents-without-being-evil/11352575#11352575 –

6
private static class User32 
{ 
    [DllImport("User32.dll")] 
    internal static extern IntPtr SetForegroundWindow(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 

    internal static readonly IntPtr InvalidHandleValue = IntPtr.Zero; 
    internal const int SW_MAXIMIZE = 3; 
} 
public void Activate() 
{ 
    Process currentProcess = Process.GetCurrentProcess(); 
    IntPtr hWnd = currentProcess.MainWindowHandle; 
    if (hWnd != User32.InvalidHandleValue) 
    { 
     User32.SetForegroundWindow(hWnd); 
     User32.ShowWindow(hWnd, User32.SW_MAXIMIZE); 
    } 
} 
+0

Хм, это не выигрывает никаких призов за элегантность, разве нет хорошего родного .Net-способа? – RedFilter

+0

Это работает. – RedFilter

+0

От MSDN: «Функция SetForegroundWindow помещает поток, который создал указанное окно на переднем плане и активирует окно». При этом ваше приложение может заставить окно перейти на передний план, а пользователь работает с другим приложением. –

2

После большого количества проб и ошибок я добрался до этого кода. Это проверено. Метод BringToFront вызывается в вашей форме после того, как фокус был передан на него. Это заставляет его всплывать спереди.

[DllImport("user32.dll")] 
static extern bool SetForegroundWindow(IntPtr hWnd); 

public static bool BringToFrontCustom(Form f) 
{ 
    bool toReturn = true; 
    try 
    { 
     //This is the same as the name of the executable without the .exe at the end    
     Process[] processes = Process.GetProcessesByName("MyFormName"); 

     SetForegroundWindow(processes[0].MainWindowHandle); 
     f.BringToFront(); 
    } 
    catch(Exception e) 
    { 
     toReturn = false; 
     MessageBox.Show("Something went wrong, Please bring the window to front manually"); 
    } 
    return toReturn; 
} 
7

Примечание. Ниже я скопировал самый voted answer в linked question, который был закрыт как дубликат этого. Этот ответ - единственный чистый ответ C#, который я нашел, который решает эту проблему.

this.WindowState = FormWindowState.Minimized; 
this.Show(); 
this.WindowState = FormWindowState.Normal; 

Он всегда приносит нужное окно перед всеми остальными.

+0

Возможно, это не красиво, но в моем (очень конкретном) случае это действительно был путь. Большое спасибо за приведение этого «up2 :-) –

+1

Любопытно, что на одной машине я мог бы использовать только' this.Activate() '. И это не сработало бы на другой машине (теоретически, той же версии Windows 7). проблема –

+0

@ Daniel, Согласен! Другие ответы не работали почти так же хорошо для меня, как этот подход. – John

0

Установка Form.TopMost на true заставит окно формы перейти на передний план.

0

набор .TopMost = true

и использовать

ShowDialog() 
+0

Пожалуйста, добавьте некоторое объяснение в свой ответ. Ответы только на код не приветствуются на SO. –

+0

Вызов формы.ShowDialog() вместо form.show() будет помещать форму на передний план. –

+0

И в случае mainform был установлен mainform.TopMost с true, лучше установить form.TopMost = true, прежде чем u вызывается form.ShowDialog(). –

0

На самом деле, просто позвоните Activate() внутри Shown события.

В вашей Example.Designer.cs:

this.Shown += new System.EventHandler(this.Example_Shown); 

В вашей Example.cs:

private void Example_Shown(object sender, EventArgs e) 
{ 
    this.Activate(); 
} 

Это работает, даже если ваша форма является запуск другого процесса (например: форма заставка работает в другом потоке).

0

У меня была аналогичная проблема, к которой

form.TopMost = true; 
form.Activate(); 

был вполне удовлетворительным решением.

Но это еще не гарантирует, что форма будет иметь фокус то, потому что TopMost не всегда может работать, в зависимости от того, как пользователь взаимодействовал раньше с окнами в других процессах:

TopMost does not work when used on Forms running in consecutively in different threads and closed by user code

Смежные вопросы