Windows 窗体和 ShowDialog 问题

发布于 2024-09-03 09:01:26 字数 1861 浏览 5 评论 0原文

我有一个无边框 Windows 窗体 应用程序。

主窗口使用 ShowDialog() 创建其他表单(可以单击“是”或“否”的简单对话框)。 每个创建的对话框在任务栏中都不可见,我的应用程序只有一个任务栏条目来聚焦我的应用程序(如果打开了一个对话框,则该对话框将被聚焦)。如果我使用 ALT + TAB 循环到所有打开的窗口,我也只能看到一个条目。

但是,如果在我的应用程序没有焦点时创建对话框(例如,用户启动一个长时间运行的任务,开始处理其他事情,并且在后台运行),我的应用程序会显示一个对话框“任务已完成..” ."),我想返回我的申请,事情变得越来越奇怪。

  • 如果我单击任务栏来聚焦我的应用程序,则主窗口将被聚焦(而不是对话框)。
  • 我无法使用主窗口(因为仍然有一个打开的模式对话框)。
  • Windows 7 ALT + TAB 预览显示对话框,而任务栏鼠标悬停预览显示主窗口(在正常情况下,两者都在主窗口前面显示对话框)。
  • 使我的应用程序再次可用的唯一方法是按 ALT + TAB 进入条目并关闭模式对话框。
  • 如果我使用 ALT + TAB 仅对话框会被带到前面,主窗口仍然在后台。

有办法防止这种情况发生吗? 我知道该怎么做,但大多数客户认为应用程序崩溃了,因为主窗口没有响应。

更新:

解决方案是将顶级窗口传递给 ShowDialog() 方法(在大多数情况下,如果以“this”形式使用)。

因为我不想重构我的整个代码,并且我的所有表单都继承自“MyCustomFormBase”,所以这里有一个效果很好的小解决方案。

Public Class MyCustomFormBase

    Public Shared Property ApplicationMainForm() As Form
        Get
            Return _applicationMainform
        End Get
        Set(ByVal value As Form)
            _applicationMainform = value
        End Set
    End Property
    Private Shared _applicationMainform As Form

    Public Shadows Function ShowDialog() As DialogResult
        If MyCustomFormBase.ApplicationMainForm IsNot Nothing Then
            Return MyBase.ShowDialog(MyCustomFormBase.ApplicationMainForm)
        Else
            Return MyBase.ShowDialog()
        End If
    End Function

    Public Shadows Function ShowDialog(ByVal owner As IWin32Window) As DialogResult
        Return MyBase.ShowDialog(owner)
    End Function

End Class

在主窗口的构造函数中我使用了

MyCustomFormBase.ApplicationMainForm = Me

一次。它帮助我重构了半天;)

I have a borderless Windows Forms application.

The main window creates other forms (simple dialogs where I can click yes or no) with ShowDialog().
Every created dialog is not visible in the taskbar, my application has only one taskbar entry that focuses my application (and if a dialog is open that one is focused). If I use ALT + TAB to cycle to all open windows I only see one entry, too.

However, if the dialog is created while my application doesn't have the focus (for example the user starts a long running task, starts to work on something else and while being in the background, my application shows a dialog "Task done...") and I want to go back to my application, things are getting strange.

  • If I click on the taskbar to focus my application, the main window is focused (not the dialog).
  • I can't use the main window (because there is still an open modal dialog).
  • Windows 7 ALT + TAB preview shows the Dialog while the taskbar mouseover preview shows the main window (in normal behavior both show the dialog in front of the main window).
  • The only way to make my application usable again is to ALT + TAB to the entry and close the modal dialog.
  • If I use ALT + TAB only the dialog is brought to the front and the main window is still in the background.

Is there a way to prevent that from happening?
I know what to do, but most customers think the application crashed since the main window doesn't respond.

Update:

The solution is to pass the top level window to the ShowDialog() method (in most cases and if used in a form that would be the "this").

Since I didn't wanted to refactor my entire code, and all my forms inherit from "MyCustomFormBase" here is a little solution that works very well.

Public Class MyCustomFormBase

    Public Shared Property ApplicationMainForm() As Form
        Get
            Return _applicationMainform
        End Get
        Set(ByVal value As Form)
            _applicationMainform = value
        End Set
    End Property
    Private Shared _applicationMainform As Form

    Public Shadows Function ShowDialog() As DialogResult
        If MyCustomFormBase.ApplicationMainForm IsNot Nothing Then
            Return MyBase.ShowDialog(MyCustomFormBase.ApplicationMainForm)
        Else
            Return MyBase.ShowDialog()
        End If
    End Function

    Public Shadows Function ShowDialog(ByVal owner As IWin32Window) As DialogResult
        Return MyBase.ShowDialog(owner)
    End Function

End Class

In the constructor of the main window I use

MyCustomFormBase.ApplicationMainForm = Me

once. It helped me half a day refactoring ;)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那小子欠揍 2024-09-10 09:01:26

您是否尝试将对主窗口的引用传递给 ShowDialog 调用?

// assuming this code is in the main form (so "this" refers to the main form)
DialogForm dialog = new DialogForm();
DialogResult result = dialog.ShowDialog(this);

引用此重载的文档

此版本的 ShowDialog 方法
允许您指定特定的表单
或将拥有该对话框的控件
显示的框。如果您使用
此方法的版本没有
参数,显示对话框
将自动归
您当前活动的窗口
应用程序。

Have you tried passing a reference to the main window to ShowDialog calls?

// assuming this code is in the main form (so "this" refers to the main form)
DialogForm dialog = new DialogForm();
DialogResult result = dialog.ShowDialog(this);

Quote from the documentation of this overload:

This version of the ShowDialog method
allows you to specify a specific form
or control that will own the dialog
box that is shown. If you use the
version of this method that has no
parameters, the dialog box being shown
would be owned automatically by the
currently active window of your
application.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文