3

听起来应该很奇怪,但这只是我的爱好。我想要一个(自定义)消息框弹出一个 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的行为。

4

6 回答 6

3

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

于 2011-12-19T21:26:20.230 回答
2

本质上,您不能在“阻塞”呼叫中轻松做到这一点。您可以很容易地做的是将执行删除所需的信息或执行操作的委托传递给表单。当他们单击确定时,您只需执行操作。如果他们激活父表单,则只需关闭子表单。

于 2011-12-19T21:16:52.857 回答
1

您希望用户能够单击背景窗口来取消对话框吗?将处理程序添加到背景窗口,以便当用户单击它时,您可以检查是否显示了非模态窗口,如果显示则关闭它。

听起来很简单,但您需要小心处理对背景窗口和子窗口的每一次可能点击。这听起来像是一罐我不想下去的蠕虫。

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

于 2011-12-19T21:19:34.193 回答
1

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

[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.

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

于 2012-09-05T15:09:03.423 回答
0

您可以执行以下操作:

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

不过,我不确定我是否会推荐它——我不确定它有多稳定,我也不确定如果您在父表单上单击“删除”按钮而“ dialog' 已启动(它会先关闭第一个对话框,还是将其保留?可能是后者,这可能会变得混乱)。

于 2011-12-19T21:19:55.597 回答
0

更简单的方法:将表单的“TopMost”属性设置为 True。然后它会像阻塞一样

于 2016-02-22T08:29:55.480 回答