Каков «правильный» способ принести приложение Windows Forms на передний план?

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

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

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

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

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

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

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

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

Заметка. Ниже я скопировал самый проголосовавший ответ в связанном вопросе, который был закрыт как дубликат этого. Этот ответ – единственный чистый ответ C #, который я нашел, который решает эту проблему.

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

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

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

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

После большого количества проб и ошибок я добрался до этого кода. Это проверено. Метод 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; } 

После нескольких попыток я обнаружил комбинацию:

 form.Show(); form.WindowState = FormWindowState.Normal; form.Activate(); 

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

set .TopMost = true

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

 ShowDialog() 

Собственно, просто вызовите 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(); } 

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

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

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

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

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

TopMost не работает при использовании в Forms, запущенных последовательно в разных streamах и закрытых по пользовательскому коду

Как уже было сказано в другом ответе, один (конечно, неэлегантный) способ сделать это будет с помощью user32.dll и вызовом собственных методов, это может быть справедливо, если мы используем некоторый несвязанный процесс или stream от вызывающего windows, который был установленный в главном вызывающем абоненте в качестве фонового windows (например: всегда сверху для windows, которое мы хотим видеть сверху).

это было частично скопировано, но только для удобства:

 public enum WindowPos : int { HWND_NOTOPMOST=-2, HWND_TOPMOST=-1, HWND_TOP=0, HWND_BOTTOM=1 } public enum WindowFlags : uint { SWP_NOSIZE=0x0001, SWP_NOMOVE=0x0002, SWP_NOZORDER=0x0004, SWP_NOREDRAW=0x0008, SWP_NOACTIVATE=0x0010, SWP_FRAMECHANGED=0x0020, /* The frame changed: send WM_NCCALCSIZE */ SWP_SHOWWINDOW=0x0040, SWP_HIDEWINDOW=0x0080, SWP_NOCOPYBITS=0x0100, SWP_NOOWNERZORDER=0x0200, /* Don't do owner Z ordering */ SWP_NOSENDCHANGING=0x0400 /* Don't send WM_WINDOWPOSCHANGING */ } public enum ShowWindowCommands : int { SW_HIDE=0, SW_SHOWNORMAL=1, SW_NORMAL=1, SW_SHOWMINIMIZED=2, SW_SHOWMAXIMIZED=3, SW_MAXIMIZE=3, SW_SHOWNOACTIVATE=4, SW_SHOW=5, SW_MINIMIZE=6, SW_SHOWMINNOACTIVE=7, SW_SHOWNA=8, SW_RESTORE=9, SW_SHOWDEFAULT=10, SW_FORCEMINIMIZE=11, SW_MAX=11 } private static class User32 { [DllImport("user32.dll")] internal static unsafe extern IntPtr SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] internal static unsafe extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] internal static unsafe extern bool SetWindowPos(IntPtr hWnd, int hWndPutAfter, int x, int y, int cx, int cy, uint flags); [DllImport("user32.dll")] internal static unsafe extern IntPtr SetFocus( IntPtr hWnd ); } public void Activate() { Process currentProcess = Process.GetCurrentProcess(); IntPtr hWnd = currentProcess.MainWindowHandle; if (hWnd != IntPtr.Zero) { User32.SetWindowPos(hWnd, (int)WindowPos.Top, 0, 0, 0, 0, (uint)(WindowFlags.SWP_NOMOVE | WindowFlags.SWP_NOSIZE)); User32.ShowWindow(hWnd, (int)ShowWindowCommands.SW_SHOW); User32.SetForegroundWindow(hWnd); User32.SetFocus( hWnd ); } } 

Для полноты я добавил большинство ссылок из констант, доступных в окне SDK

Вместо использования windowstate minim или topmost = false и т. Д. И т. Д. …

У меня есть приложение Winform … он запускает процедуру автоматизации – я хотел, чтобы приложение было сведено к минимуму, когда последовательность автоматизации была выполнена, а затем снова представлена ​​после завершения последовательности автоматизации.

Это было просто: просто сделайте форму невидимой, пока другой процесс / нить / все работает

  //hide the app this.Visible=false; //do something some_form.ShowDialog(); doSomethingHere(); //reshow the app this.visible=true; 
  • SendKeys.Send и ключ Windows
  • Как удалить выбранный DataGridViewRow и обновить связанную таблицу базы данных?
  • Предварительный просмотр команд ZPL II с использованием .NET WinForm перед отправкой на принтер Zebra
  • Проверка работы приложения Windows
  • Добавьте несколько изображений в тело электронной почты (inline) с помощью приложения windows c #
  • Как автоматически перейти к нижней части многострочного текстового поля?
  • Как печатать значения из элемента управления DataGridView
  • Скрытие нежелательных свойств в пользовательских элементах управления
  • Как я могу сделать ComboBox недоступным для редактирования в .NET?
  • Как получать уведомления устройства Plug & Play без формы windows
  • Рисование прозрачной кнопки
  • Interesting Posts

    Нужно ли мне активировать Windows 8, если я использовал его раньше?

    Apache Tomcat не отображается в среде Runtime сервера Eclipse

    Можно ли установить значок для приложения, зарегистрированного в OpenWith?

    Как заставить sshfs работать в Debian? (Я получаю / dev / fuse: разрешение отклонено)

    Как открыть второе действие при нажатии кнопки в приложении для Android

    Как я могу добавить два массива 2d (стадия), используя вложенные для циклов?

    Размер файла ОС ОС Windows 8 меньше?

    Как показать список установленных приложений в списке без флажка, который не проверяется при прокрутке списка?

    Создайте нулевой заполненный 2D-массив с единицами в позициях, индексированных вектором

    Совместные запросы NSURLSession с Alamofire

    Загрузка файла с помощью Angularjs вызывает redirect маршрутизатора

    Ускорить bitstring / bit операции в Python?

    Вызовите действие управляемого компонента JSF при загрузке страницы

    Как конкатенировать строки с заполнением в sqlite

    Ошибка RE: незаконная последовательность байтов в Mac OS X

    Давайте будем гением компьютера.