C# 将 Windows 窗体应用程序置于前台的“正确”方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1463417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 17:48:24  来源:igfitidea点击:

What is the "right" way to bring a Windows Forms Application to the foreground?

c#winformsvisual-studio-2008

提问by RedFilter

I am writing a Windows Forms Application in C#. I need to be able to bring it to the foreground. After some Googling and experimentation, I have a working solution that looks pretty hacky.

我正在用 C# 编写 Windows 窗体应用程序。我需要能够把它带到前台。经过一些谷歌搜索和实验后,我有一个看起来很hacky的可行解决方案。

I would like to know the elegant way to do this, if there is one. I need the app to restore and come to the foreground whether it was minimized, or not minimized but in background.

我想知道这样做的优雅方式,如果有的话。我需要应用程序来恢复并进入前台,无论它是最小化的,还是没有最小化但在后台。

Current code looks like this:

当前代码如下所示:

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

采纳答案by bobbymcr

Have you tried Form.Activate?

你试过Form.Activate吗?

This code seems to do what you want, by restoring the form to normal size if minimized and then activating it to set the focus:

这段代码似乎可以满足您的需求,通过将表单恢复到正常大小(如果最小化)然后激活它以设置焦点:

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

this.Activate();

Warning: this is annoying! If it's just an app for your personal use, as you say, maybe you can live with it. :)

警告:这很烦人!如果它只是供您个人使用的应用程序,如您所说,也许您可​​以接受它。:)

回答by Joel Coehoorn

You can set .TopMostto true, call DoEvents(), and then set .TopMostback to false. It's still hackish, but if Activate and Show aren't working it's better than minimizing/re-showing.

您可以设置.TopMost为 true,调用DoEvents(),然后再设置.TopMost回 false。它仍然是骇人听闻的,但如果 Activate 和 Show 不起作用,它比最小化/重新显示要好。

回答by Jacob Seleznev

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

回答by Democrats

After a lot of trial and error I got to this code. This is tested. The BringToFront method is called on your form after the focus has been passed on to it. This makes it pop up in front.

经过大量的反复试验,我得到了这段代码。这是经过测试的。焦点传递给窗体后,将在窗体上调用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;
}

回答by John

Note. Below I have copied the most voted answerin a linked questionclosed as a duplicate to this one. That answer is the only pure C# answer I've found that solves this problem.

笔记。下面我复制了一个链接问题中投票最多的答案,作为这个问题的副本。该答案是我发现的唯一可以解决此问题的纯 C# 答案。

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

It always brings the desired window to the front of all the others.

它总是将所需的窗口放在所有其他窗口的前面。

回答by Jim Fell

Setting Form.TopMostto truewill force the form window to the foreground.

设置Form.TopMosttrue将强制窗体窗口到前台。

回答by cortexm_0

set .TopMost = true

.TopMost = true

and use

并使用

ShowDialog()

回答by codenamezero

Actually, just call Activate()inside Shownevent.

实际上,只需调用Activate()内部Shown事件。

In your Example.Designer.cs:

在您的Example.Designer.cs

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

In your Example.cs:

在您的Example.cs

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

This worked even if your form is being launch by another process (ex: a splash screen form running in a different thread).

即使您的表单正在由另一个进程启动(例如:在不同线程中运行的启动屏幕表单),这也有效。

回答by Philip

I had a similar problem, to which

我有一个类似的问题,对此

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

was quite a satisfying solution.

是一个相当令人满意的解决方案。

But it's still not guaranteed that the form will have focus then, because TopMostmight not always work, depending on how the user has interacted before with the windows in other processes:

但是仍然不能保证该表单将具有焦点,因为TopMost可能并不总是有效,这取决于用户之前与其他进程中的窗口的交互方式:

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

当在不同线程中连续运行并由用户代码关闭的表单上使用时,TopMost 不起作用

回答by R.McNeil

Instead of using windowstate minimize or topmost=false etc etc...

而不是使用 windowstate 最小化或 topmost=false 等...

I have a Winform App... it launches an automation routine - I wanted the app minimized when the automation sequence is performed then presented again after the automation sequence was complete.

我有一个 Winform 应用程序......它启动了一个自动化例程 - 我希望在执行自动化序列时最小化该应用程序,然后在自动化序列完成后再次呈现。

It was easy - just make the form not visible while the other process/thread/ whatever is running

这很容易 - 只需在其他进程/线程/任何正在运行的过程中使表单不可见

 //hide the app

 this.Visible=false;

 //do something 

 some_form.ShowDialog();
 doSomethingHere();

 //reshow the app

 this.visible=true;