带所有者窗口显示服务通知MessageBox报错,求置顶解决方案
为了让MessageBox保持置顶,使用代码MessageBox.Show(new Form { TopMost = true }, message, heading, buttonType, icon, MessageBoxDefaultButton.Button1, Options);实现。该代码在普通Form中调用正常,但从作为模态对话框弹出的子窗体(popProductionConfirmation)调用时抛出异常:
Exception: Showing a service notification message box with an owner window is not a valid operation. Use the Show method that does not take an owner.
尝试传入MessageBoxOptions.DefaultDesktopOnly和MessageBoxOptions.ServiceNotification参数均无效。相关调用代码如下:
子弹窗调用方法
private void callMyMethod() { ShowMessageInMessageBox("Automatic Posting Done", "Production Confirmation", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxOptions.DefaultDesktopOnly); } private void ShowMessageInMessageBox(string message, string heading, MessageBoxButtons buttonType, MessageBoxIcon icon, MessageBoxOptions Options) { CommonMethods.ShowMessageInMessageBox(message, heading, buttonType, icon, Options, this); }
CommonMethods类中的MessageBox方法
public static void ShowMessageInMessageBox(string message, string heading, MessageBoxButtons buttonType, MessageBoxIcon icon, MessageBoxOptions Options, IWin32Window owner = null) { if (owner == null) { MessageBox.Show(new Form { TopMost = true }, message, "BTS: " + heading, buttonType, icon, MessageBoxDefaultButton.Button1, Options); } else { MessageBox.Show(owner, message, "BTS: " + heading, buttonType, icon, MessageBoxDefaultButton.Button1, Options); } }
父窗口创建子弹窗代码
popProductionConfirmation objpopProductionConfirmation; objpopProductionConfirmation = new popProductionConfirmation(); objpopProductionConfirmation.ShowDialog();
1. 修复Owner与服务通知选项的冲突逻辑
异常根源在于:当使用DefaultDesktopOnly或ServiceNotification这类服务通知类选项时,系统不允许指定Owner窗口,因为这类消息框是面向整个桌面而非某个窗口的。修改CommonMethods的逻辑,自动识别这类选项并跳过Owner传递:
public static void ShowMessageInMessageBox(string message, string heading, MessageBoxButtons buttonType, MessageBoxIcon icon, MessageBoxOptions options, IWin32Window owner = null) { // 检查是否包含服务通知类选项 bool isServiceNotification = (options & (MessageBoxOptions.DefaultDesktopOnly | MessageBoxOptions.ServiceNotification)) != 0; if (isServiceNotification) { // 服务通知类消息框不指定Owner,直接添加TopMost选项确保置顶 MessageBox.Show(message, "BTS: " + heading, buttonType, icon, MessageBoxDefaultButton.Button1, options | MessageBoxOptions.TopMost); } else { // 常规场景:如果没有传入Owner,创建置顶的临时Form作为Owner var targetOwner = owner ?? new Form { TopMost = true }; MessageBox.Show(targetOwner, message, "BTS: " + heading, buttonType, icon, MessageBoxDefaultButton.Button1, options); } }
2. 直接使用TopMost选项替代临时Form
不需要创建临时Form,直接通过MessageBoxOptions.TopMost让消息框置顶,同时避免和服务通知选项的冲突。修改子窗体的调用代码:
private void callMyMethod() { // 替换DefaultDesktopOnly为TopMost选项 ShowMessageInMessageBox("Automatic Posting Done", "Production Confirmation", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxOptions.TopMost); }
3. 确保模态子窗体的Owner传递正确
如果不需要服务通知类功能,直接传递子窗体作为Owner,同时确保消息框的置顶属性生效。此时可以去掉所有服务通知相关选项,仅保留必要的参数,让消息框默认依附于子窗体并保持置顶。
内容的提问来源于stack exchange,提问作者thrainder

