- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想显示一个 MessageBox
,它仅对单个表单具有模态,并允许线程上的其他顶级窗口保持事件状态。 WinForms 禁用当前线程上的所有窗口,无论是显示自定义模式窗体还是使用 MessageBox
类。
我已经尝试了多种不同的方法来解决这个问题,包括重新启用任何其他顶级窗口(使用 Win32 EnableWindow
函数)和 p/调用 native MessageBox
功能。这两种方法都有效,但键盘快捷键无法操作,包括在控件之间移动的选项卡、退出以取消打开的菜单以及最重要的菜单快捷键。
我可以通过在显示 MessageBox
时安装键盘 Hook 然后在事件窗体上直接调用 ProcessCmdKey
来使菜单快捷键工作,但其他键盘快捷键仍然不起作用工作。我想我可以继续并添加更多 hack 来使这些其他案例起作用,但我想知道是否有更好的方法。
注意,这与being non-blocking无关,但关于不禁用当前线程上的所有窗口。然而,碰巧解决方案可能是相似的。
最佳答案
您在这里遇到的基本问题是 MessageBox.Show() 抽取自己的消息循环以使自己成为模态。此消息循环内置于 Windows 中,完全不知道 Winforms 消息循环是什么样的。因此,当您使用 MessageBox 时,Winforms 在其消息循环中所做的任何特殊操作都不会发生。这是键盘处理:检测助记符、实现导航和调用 ProcessCmdKey() 等方法,以便表单可以实现自己的快捷键击。通常不是问题,因为它应该是模态的并且忽略用户输入。
恢复此功能的唯一实用方法是在其自己的线程中显示消息框。这在 winapi 中是正式允许的,窗口的所有者可以是另一个线程拥有的窗口。但这是 Microsoft 在将代码添加到 .NET 2.0 中以检测线程错误时并未实现的规则。解决该代码需要一个 IWin32Window 作为消息框所有者,它不是一个控件。
向您的项目添加一个新类并粘贴此代码:
using System;
using System.Threading;
using System.Windows.Forms;
public class NonModalMessageBox : IWin32Window {
public NonModalMessageBox(Form owner, Action<IWin32Window> display) {
this.handle = owner.Handle;
var t = new Thread(new ThreadStart(() => display(this)));
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
public IntPtr Handle {
get { return handle; }
}
private IntPtr handle;
}
然后像这样使用它:
new NonModalMessageBox(this, (owner) => {
MessageBox.Show(owner, "Testing", "Non-modal");
});
其中 this 显示消息框时应禁用的 Form 对象。我几乎无法让您对这个 hack 感觉更好,如果 FUD 过于强烈,那么您确实需要用您自己的 Form 类重新实现 MessageBox,这样您就可以使用 Show() 而不是 ShowDialog()。已经完成了。
关于c# - MessageBox模态到单一形式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30478666/
我来自 Asp.Net 世界,试图理解 Angular State 的含义。 什么是 Angular 状态?它类似于Asp.Net中的ascx组件吗?是子页面吗?它类似于工作流程状态吗? 我听到很多人
我一直在寻找 3 态拨动开关,但运气不佳。 基本上我需要一个具有以下状态的开关: |开 |不适用 |关 | slider 默认从中间开始,一旦用户向左或向右滑动,就无法回到N/A(未回答)状态。 有人
我是一名优秀的程序员,十分优秀!