如何创建非模态表单但阻止?

时间:2011-12-19 21:08:33

标签: c# .net winforms blocking non-modal

听起来应该很奇怪,但这只是为了我的爱好。我想要一个(自定义)消息框弹出YesNo按钮,理想情况下应该阻止代码。但我应该可以点击父表单,这样我就可以关闭消息框,而不必专门点击消息框按钮(相当于在消息框上单击否)。

类似的东西:

     void Foo()
     {
         CustomMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo);
         //block the code here, but user should be able to click on form, so that its equivalent to have clicked No;
         //if clicked No, return;

         //delete.
     }

所以我认为解决方案是使自定义消息框非模态 - 以便用户可以单击表单,但我无法阻止代码..我该怎么做?

看起来像这样:

 void Foo()
 {
     NonModalMsgBox.Show("do you really wanna delete?", CustomMsgBox.Buttons.YesNo);
     //block thread till user clicks on form or messagebox buttons.
     //unblock when user clicks.
     //if No, return;

     //delete.
 }

编辑:我知道这不是一个标准做法,我知道非模态形式不会阻止,而模态形式可以。所以请不要建议对模态形式或非模态形式的行为感到满意。我的问题是有没有办法用Windows窗体模拟ContextMenu的行为。

6 个答案:

答案 0 :(得分:3)

你可以很容易地解决这个问题。创建并使用模式对话框,但覆盖对话框的WndProc并处理WM_MOUSEDOWN事件。检查鼠标向下的位置,如果它位于父窗口之上但不在对话框本身之上,则只需关闭对话框。

答案 1 :(得分:2)

基本上你不能轻易地在“拦截”电话中这样做。您可以轻松完成的任务是将执行删除所需的信息或执行操作的委托传递给表单。单击“确定”后,您只需执行操作即可。如果他们激活父表单,则只需关闭子表单。

答案 2 :(得分:1)

您希望用户能够单击背景窗口取消对话框吗?在后台窗口中添加一个处理程序,以便当用户点击它时,检查是否显示非模态窗口,如果是这样的话。

听起来很简单,但您需要小心处理背景窗口和子窗口上的所有可能的点击。这听起来像是一堆蠕虫我不想失望。

也许您可以检测非模态对话框是否失去焦点并自动关闭它。我可以看到这种行为对于一个简单的“确认删除”对话框是有意义的,但作为用户,我的第一反应是垃圾邮件ESC键以关闭对话框。

答案 3 :(得分:1)

另一种处理方法是在调用ShowDialog时手动启用父窗体,from here

[DllImport("user32.dll")]
private static extern bool EnableWindow(IntPtr hWnd, bool enable);

internal static DialogResult ShowDialogSpecial(this Form formToBeShown, Form parent)
{
    parent.BeginInvoke(new Action(() => EnableWindow(parent.Handle, true)));
    formToBeShown.ShowDialog(parent);

    return formToBeShown.DialogResult;
}

只需从任何父表单调用扩展方法,如下所示:

var f = new Form();
f.ShowDialogSpecial(this);
//blocks but parent window will be active.

当然,您需要处理父表单上的点击以关闭子表单。

答案 4 :(得分:0)

您可以执行以下操作:

public void ShowMe() {
    Show();
    while (!_receivedDeactivateEvent)
        Application.DoEvents();
}

我不确定我是否会推荐它 - 我不确定它会有多稳定,也不确定它是否会按照你想要的方式行事在'对话框中删除父表单上的按钮。是(它会先关闭第一个对话框,还是把它放好?可能是后者,可能会变得混乱)。

答案 5 :(得分:0)

更简单的方法:设置表格" TopMost"财产是真的。然后它会像阻止