在非模态状态下显示已禁用的表单时遇到一些问题。以下是示例代码:
public partial class Form1 : Form
{
// ....
private void button1_Click(object sender, EventArgs e)
{
try
{
Form2 form = new Form2();
form.Enabled = false;
form.Show(); // works, but form has no owner
// form.Show(this); // gives an System.InvalidOperationException
// ...
// ... my program here shows a message box, ask user for something
// ... while 'form' is shown in the background
form.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
知道为什么Show()
(没有参数)有效,但Show(this)
会出现异常吗?在我的方案中,form
必须知道其所有者才能正确显示,因此我可以执行以下操作:
form.Enabled = false;
form.Owner=this;
form.Show();
但这真的是一个很好的解决方案吗?
编辑:感谢您的快速解答。似乎我们确实在这里找到了框架中的错误。尽管您提出了建议,但我认为我会继续使用我的解决方案,因为在“显示”之后禁用表单会给用户带来难看的可见效果。
答案 0 :(得分:4)
这是一个经典的剪切和粘贴错误。看起来他们从ShowDialog()复制了代码,将禁用的表单显示为对话框确实无效。用户会被困住,不能再做任何事了。但是他们忘了在Show()方法中删除测试。只需在Show()调用后禁用它。
答案 1 :(得分:3)
来自Microsoft的参考资料来源:
public void Show(IWin32Window owner)
{
if (owner == this)
{
throw new InvalidOperationException(SR.GetString("OwnsSelfOrOwner", new object[] { "Show" }));
}
if (base.Visible)
{
throw new InvalidOperationException(SR.GetString("ShowDialogOnVisible", new object[] { "Show" }));
}
// Here!!!
if (!base.Enabled)
{
throw new InvalidOperationException(SR.GetString("ShowDialogOnDisabled", new object[] { "Show" }));
}
if (!this.TopLevel)
{
throw new InvalidOperationException(SR.GetString("ShowDialogOnNonTopLevel", new object[] { "Show" }));
}
if (!SystemInformation.UserInteractive)
{
throw new InvalidOperationException(SR.GetString("CantShowModalOnNonInteractive"));
}
if (((owner != null) && ((((int) UnsafeNativeMethods.GetWindowLong(new HandleRef(owner, Control.GetSafeHandle(owner)), -20)) & 8) == 0)) && (owner is Control))
{
owner = ((Control) owner).TopLevelControlInternal;
}
顺便说一下,声明了a MS Connect bug。
答案 2 :(得分:2)
那个或致电Show(this)
然后禁用它是我能想到的唯一两种方式。