【问题标题】:VB.net Bring Window to FrontVB.net 将窗口置于前面
【发布时间】:2011-10-07 22:33:36
【问题描述】:

VB.net 2010 中的什么代码我需要设置一个窗口到屏幕的前面。

我想要实现的是显示一个紧急警报类型,它是一个表单,由于某些原因我没有使用消息框。

有人建议了以下代码,但这不起作用:

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

【问题讨论】:

  • 请提供打开窗口的代码。
  • 只需frmMessage.Show()
  • 您打开的表单或打开方式必须有特定的内容。我刚刚创建了一个“hello world”项目; 2 个表单,每个表单都有一个打开另一个的按钮。打开的表单总是在最前面。
  • 您是否在不同的线程上创建表单?我发现这是一个大问题。我还没有尝试过,但我将确保我的软件通过调用主窗体在一个线程上创建所有 GUI。

标签: vb.net winforms


【解决方案1】:

设置属性 TopMost 的窗口,您需要在其他窗口的顶部就足够了。

Form.TopMost = True

【讨论】:

  • 这很好,只要目的是让表单始终处于顶部。
  • @dbasnett - 您始终可以设置 TopMost = True,然后设置 TopMost = False,这样它就不会永远保持在顶部,但在 OPs 问题中,我建议用户在执行此操作之前先执行此警报还有什么
  • @Matt - 我只是讨厌那些认为他们的问题有理由排在所有应用程序之上的应用程序。话虽如此,如果我在核电站工作,我希望反应堆熔毁信息始终处于首位。紧急应用和紧急用户可能相同也可能不同。
  • @dbasnett - 只需设置 Form.Owner 而不是 Form.TopMost(请参阅下面的答案)
【解决方案2】:

试试这个:

Me.ShowDialog()

应该有帮助。

【讨论】:

    【解决方案3】:

    如果你想要的是在 winfom 失去焦点或最小化之后带来的。在我的情况下,当我在一个按钮上打开一个 winform 时工作。

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

    【讨论】:

      【解决方案4】:

      表单加载时见下例

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

          Me.TopMost = True
      
      End Sub
      

      【讨论】:

        【解决方案5】:

        从哪里把窗口带到前面?

        MDI

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

        桌面

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

        如果您的应用程序位于另一个窗口之后,则可能看不到警告消息。

        要将application 放在前面,您需要做一些额外的工作,这是对“表单”类的“扩展”,所以用法是: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
        

        与往常一样,扩展代码需要位于单独的模块中。

        【讨论】:

          【解决方案6】:

          在单击菜单选项后,以下对我来说似乎最容易调出一个名为“项目”的表单。如有必要,将加载表格,如有必要,将其最小化,并放在前面(“焦点”)。

          Private Sub ProjectsToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles ProjectsToolStripMenuItem1.Click
          
              Me.Cursor = Cursors.WaitCursor       ' if form is slow to load for any reason
              Projects.Show()
              Me.Cursor = Cursors.Default
              Projects.WindowState = FormWindowState.Normal
              Projects.Focus()
          
          End Sub
          

          【讨论】:

            【解决方案7】:

            根据吉姆·诺兰的描述采取吉姆·诺兰所说的做法。这是确保表单正确位于所有其他表单前面以及处理表单、分配新表单的所有权和显示表单的最佳处理方式

            Dim form As Form = new Form
            form.TopMost = True
            form.Owner = Me
            form.ShowDialog()
            form.Dispose()
            

            【讨论】:

            • 这是处理打开新表单的正确方法
            【解决方案8】:

            我以这种方式解决了它(我对某人有用)-即使在调试模式下,它也会将隐藏的表单带到前面:

            Private Sub Form1_SizeChanged(sender As Object, e As EventArgs) Handles MyBase.SizeChanged
                If Me.WindowState = FormWindowState.Minimized Then
                    HideForm()
                Else
                    BringFormToFront()
                End If
            End Sub
            
            
            Private Sub NotifyIcon_Click(sender As Object, e As EventArgs) Handles NotifyIcon.Click
                'Determine which mouse button was pressed, in order to differentiate between Left/Right Mouse Button
                Dim MouseButton As System.Windows.Forms.MouseEventArgs = CType(e, MouseEventArgs)
                If MouseButton.Button = MouseButtons.Left Then
                    BringFormToFront()
                End If
            End Sub
            
            Private Sub NotifyIcon_DoubleClick(sender As Object, e As EventArgs) Handles NotifyIcon.DoubleClick
                BringFormToFront()
            End Sub
            
            Private Sub HideForm()
                Me.NotifyIcon.Visible = True
                Me.ShowInTaskbar = False
                'Windowstate controlled by user when minimizing Form
               Msgbox("Minimized, click on Notify Icon to show")
            End Sub
            
            Private Sub BringFormToFront()
                Me.NotifyIcon.Visible = False
                Me.ShowInTaskbar = True
                Me.WindowState = FormWindowState.Normal
            End Sub
            

            【讨论】:

              【解决方案9】:

              有点偏离 OP... 我有一个从菜单打开的“仪表板”。用户可以切换到其他窗口,然后再次“加载”仪表板。如果已加载,则将其置于最前面。

              声明 frmFISDash = frmFISDashboard "global"

                  If frmFISDash Is Nothing Then
                      frmFISDash = New frmFISDashboard
                      frmFISDash.Show()
                  Else
                      frmFISDash.WindowState = FormWindowState.Normal
                      frmFISDash.BringToFront()
                  End If
              

              注意 .WindowsState 的设置 - 如果表单被最小化,.bringToFront 不起作用。

              【讨论】:

                【解决方案10】:

                我知道这有点旧,但我今天遇到了类似的问题,这就是我解决它的方法。只要您不介意关闭打开的表单并创建一个新表单,它就可以工作。

                 Dim MyRemoteForm As New Form
                    MyRemoteForm = Application.OpenForms("frmManualRemote")
                    If MyRemoteForm Is Nothing Then
                        frmManualRemote.Show()
                    Else
                        frmManualRemote.Close()
                        frmManualRemote.Show()
                    End If
                

                【讨论】:

                  【解决方案11】:

                  从屏幕上绘制一个可见的最顶层表单,然后将此表单作为 ShowDialog() 调用的所有者。

                  【讨论】:

                  • 请扩展您的答案以提供代码和进一步解释。
                  • @Aibrean 我接受了他的回答并根据他的建议提供了代码
                  【解决方案12】:

                  正如另一位用户所说,我最喜欢的方法之一是设置表单所有者。通过这样做,当任一窗体被聚焦、激活等时,子窗体将始终位于父窗体之上……这样做的好处是您不必捕获任何特殊事件并执行任何特殊代码。假设您有一个主窗体 frmMain 和一个弹出窗体 frmPopup,您可以使用以下代码来确保弹出窗口始终位于主窗体的顶部,而无需使用 topmost(这可行,但可能会产生一些不好的副作用)。

                  frmPopup.show(frmMain)
                  

                  或者你可以使用更长的版本(正如上面某人发布的那样

                  frmPopup.Owner = frmMain
                  frmPopup.show()
                  

                  另一个很棒的地方是你也可以将它与 ShowDialog() 一起使用

                  frmPopup.ShowDialog(frmMain)
                  

                  我知道这是一篇旧帖子,但也许仍在寻找简单解决方案的人会发现这个。它确实帮助改进了我的程序的功能,而且代码比我以前使用的少得多。

                  【讨论】:

                    【解决方案13】:

                    一个小技巧:

                    me.hide()
                    me.visible = true
                    

                    【讨论】:

                      【解决方案14】:

                      只需设置您想要显示在顶部的表单的Owner 属性:

                      Dim frmMessage As New Form()
                      frmMessage.Owner = frmMain   'frmMain is the form creating the message window
                      frmMessage.Show()
                      

                      现在frmMessage 将始终位于frmMain 之上,无论焦点如何。

                      【讨论】:

                      • 这不是一个好的解决方案,原因与 form.Activate() 相同。如果你有 FrmMain 调用 FrmSomething 有弹出窗口,这将无法正常工作
                      • “有弹出窗口”是什么意思?为什么它不能正常工作?
                      • 假设您有一个frmmain,它调用frmsecond,您将所有者设置为frmmain。现在 frmsecond 调用 frmthree 并将所有者设置为 frmsecond 它不会出现在 frmsecond 之上,但它会在 frmsecond 之后。在这种情况下,真正让它工作的唯一方法是使用 topmost。
                      【解决方案15】:

                      我用:

                      dim tempResult as dialogResult = frmName.showDialog()
                      

                      并以被调用的形式:

                      me.dialogResult = dialogResult.{OK, Abort, whatever}
                      

                      调用表单代码在继续执行之前等待被调用表单的结果。

                      【讨论】:

                      • 这并不能保证表单会被推到其他表单的前面,他说他没有使用消息框、msgbox 或任何类似的东西
                      【解决方案16】:

                      如果没有任何效果,请尝试右键单击并选择置于前面。如果其他图像覆盖了必须在前面的图像,只需右键单击每个图像,然后根据需要选择发送到后面。

                      【讨论】:

                      • 这不起作用,因为该应用程序只允许您在调试期间仅右键单击活动表单。
                      【解决方案17】:

                      我的要求是弹出一个可能最小化的应用程序,并使其最大化并处于活动状态。在网上搜索了一下之后,我在一个 c++ 论坛中找到了部分答案。

                      WindowState = FormWindowState.Maximized
                      Me.Activate()
                      

                      这使我的应用程序处于任何状态(最大、最小、大、小、落后的东西)。它把它带到前面并在屏幕上最大化。即在屏幕上弹出它以便我可以看到它!

                      【讨论】:

                        【解决方案18】:

                        尝试使用 .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 解释的最佳答案。
                        【解决方案19】:

                        试试

                        me.Activate()
                        

                        这样就不行了

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

                        My Case

                        EDIT2:

                        似乎有几件事有效。以上以及

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

                        还有

                        Form2.ShowDialog()
                        

                        还有

                        Form2.Visible = True
                        

                        【讨论】:

                        • Me.Activate() 未列为下拉列表,但它可以工作。不要问为什么。我很欣赏对我有用的答案的反对票:)
                        • 激活也对我有用。 BringToFront 可用于 mdi 子级。
                        • 当然不能保证可以正常工作,Windows 会阻止您将窗口推到用户面前。注意闪烁的任务栏按钮。
                        • 如果您试图让弹出窗口成为焦点,而它是主表单顶部的表单弹出窗口,则此方法不起作用。
                        • 完美!对于表单,我同时使用两者,因此如果表单未打开,我将打开它,但如果它打开,则将其带到顶部。感谢您的回答:frmMain.Activate() frmMain.Show()
                        【解决方案20】:
                        <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);
                        

                        这会将窗口带到屏幕前面。

                        【讨论】:

                        • 因为我的解决方案适用于所有窗口,而不仅仅是 .NET 表单。如果表单被最小化,它也可以工作,托管方式不会。
                        猜你喜欢
                        • 2011-11-04
                        • 2012-10-08
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2012-08-18
                        • 1970-01-01
                        相关资源
                        最近更新 更多