VB.net将窗口置于顶层

14

在VB.net 2010中,我需要什么代码才能将窗口置于屏幕前面。

我的目标是显示一种紧急警报类型,它是一个表单,由于某些原因我不使用消息框。

有人建议使用以下代码,但这并没有起作用:

  Private Sub frmMessage_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.BringToFront()
    End Sub

请提供打开窗口的代码。 - Tim Murphy
只需使用 frmMessage.Show() 即可。 - developer__c
你打开窗体的方式或者特定的窗体本身一定有些问题。我刚创建了一个“hello world”项目,其中包含两个窗体,每个窗体都有一个按钮可以打开另一个窗体。被打开的窗体总是在最上面。 - Tim Murphy
你是否在不同的线程上创建表单?我发现这是一个重大问题。虽然我还没有尝试过,但我将确保我的软件通过调用主表单来创建所有GUI都在一个线程上。 - Hand-E-Food
20个回答

25

只需要设置窗口的TopMost属性即可将其置于其他窗口之上。

Form.TopMost = True

3
只要意图是让表单始终置顶,那么这样做就很好。 - dbasnett
@dbasnett - 你可以始终将TopMost设置为True,然后再将其设置为False,这样它就不会永远保持在最上面,但在OP的问题中,我建议用户在执行任何其他操作之前应该处理此警报。 - Matt Wilko
2
@Matt - 我讨厌那些假设他们的问题应该在所有应用程序之上的应用程序。话虽如此,如果我在核电站工作,我会希望反应堆熔毁消息始终处于最高位置。应用程序的紧急性和用户的紧急性可能相同,也可能不同。 - dbasnett
@dbasnett - 只需设置Form.Owner而不是Form.TopMost(请参见下面的答案) - alldayremix

13

尝试

me.Activate()

这个应该可以解决问题。

编辑:我谷歌搜索以找到我的答案的备份。

我的情况

编辑2:

似乎有几件事情可以起作用,如上所述。

''depending on setup
Me.Show
Form2.Show()

同时

Form2.ShowDialog()

同样

Form2.Visible = True

Me.Activate()没有在下拉列表中列出,但它确实起作用。不要问为什么。我感谢那些给我点赞的人 :) - sealz
激活对我也总是有效的。BringToFront 与 mdi 子窗体一起使用。 - Miroslav Zadravec
6
不能保证一定能成功,Windows会阻止窗口强行跳出。请注意闪烁的任务栏按钮。 - Hans Passant
1
如果您正在尝试使一个弹出窗口成为在主窗口之上的表单的弹出窗口时,这种方法不起作用。 - DotNet Programmer
完美!对于表单,我同时使用两种方式。如果表单未打开,则打开它;如果已经打开,则将其置于顶部。感谢您的答案:frmMain.Activate() frmMain.Show() - AquaAlex

7
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function FindWindow( _
     ByVal lpClassName As String, _
     ByVal lpWindowName As String) As IntPtr
End Function

<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

现在,请输入您想要置于最前面的窗口名称,并执行以下操作:
string name = "Untitled - Notepad";
IntPtr ptr = FindWindow(null, name);
SetForegroundWindow(ptr);

这将把窗口带到屏幕的最前面。

4
因为我的解决方案适用于所有窗口,而不仅仅是.NET表单。即使表单被最小化,我的方案也能够奏效,但托管的方法不能。 - Nahydrin

4

如果你想把窗体带到前面来,可以在winform失去焦点或最小化后进行操作。我的情况是,在按钮上打开一个winform时有效。

    frmProducts.Show()
    'Retorre the original State
    frmProducts.BringToFront()
    frmProducts.WindowState = FormWindowState.Normal

4

尝试使用.Shown事件。这是一个三个表单测试的代码。在按钮点击事件结束时,Form3应该在Form2的上面,在Form1的上面。

Public Class Form1
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Me.SendToBack()
        Dim f2 As New Form2
        f2.Show()
        Dim f3 As New Form3
        f3.Show()
    End Sub
End Class

Public Class Form2
    Private Sub Form2_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
        Me.BringToFront()
    End Sub
End Class

Public Class Form3
    Private Sub Form3_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
        Me.BringToFront()
    End Sub
End Class

在我看来,这是最好的答案,并且附有fcm的解释。 - 8oris

1
当表单加载时,请参见以下示例:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Me.TopMost = True

End Sub

1

从哪里将窗口置于前台?

MDI

在具有多个表单的 MDI 中,form.BringToFront() 就足够了,这将在应用程序中将表单移动到顶部。您还可以在呈现警告/错误时使用 form.ShowDialog() 方法。

桌面

在您的桌面上可能有多个应用程序,最好将应用程序设置为始终在顶部。

如果您的应用程序在另一个窗口后面,则警告消息可能不可见。

要将 application 置于前台,您需要进行一些额外的工作,这些是“form”类的“扩展”,因此使用方法为:form.MakeTopMost()

<Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True)> _
Private Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean
End Function

Private ReadOnly HWND_TOPMOST As New IntPtr(-1)
Private ReadOnly HWND_NOTOPMOST As New IntPtr(-2)

<System.Runtime.CompilerServices.Extension()> _
Public Sub MakeTopMost(frm As Form)
    SetWindowPos(frm.Handle(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Sub

<System.Runtime.CompilerServices.Extension()> _
Public Sub MakeNormal(frm As Form)
    SetWindowPos(frm.Handle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Sub

一如既往,扩展代码需要在单独的模块中。


0
根据Jim Nolan的描述,最好的处理方式是采取以下措施:确保该表单位于所有其他表单的前面,并处理表单的释放、分配新表单的所有权以及显示表单。
Dim form As Form = new Form
form.TopMost = True
form.Owner = Me
form.ShowDialog()
form.Dispose()

1
这是处理打开新表单的正确方法。 - user4004661

0
有点偏离主题...我有一个“仪表板”,我从菜单中打开它。用户可以切换到其他窗口,然后再次“加载”仪表板。如果已经加载,则将其置于前台。
声明frmFISDash = frmFISDashboard“全局”
    If frmFISDash Is Nothing Then
        frmFISDash = New frmFISDashboard
        frmFISDash.Show()
    Else
        frmFISDash.WindowState = FormWindowState.Normal
        frmFISDash.BringToFront()
    End If

请注意 .WindowsState 的设置 - 如果窗体被最小化了,.bringToFront 将无法工作。

0

试试这个:

Me.ShowDialog()

应该有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接