.net 如何停止显示多个对话框?

.net 如何停止显示多个对话框?,.net,vb.net,winforms,.net,Vb.net,Winforms,我有一个非常恼人的问题,我正试图找到最简单的解决方案,但我似乎一直在把它复杂化 我的程序使用ShowDialog函数显示一个自定义对话框(我使用新的构造函数创建此表单),但当我的程序在对话框中等待输入时,我的程序继续运行其他代码,(我假设是从其他消息启动的,但我仍然找不到关于此主题的好信息,因此,作为本主题的旁白,是否有人有关于此主题的参考),并到达显示对话框的同一点。因此,我最终得到了大量对话框 我的目标是防止对话框数量过多。如果程序到达此对话框起始点,我希望它等待/暂停,直到第一个对话框完成

我有一个非常恼人的问题,我正试图找到最简单的解决方案,但我似乎一直在把它复杂化

我的程序使用ShowDialog函数显示一个自定义对话框(我使用新的构造函数创建此表单),但当我的程序在对话框中等待输入时,我的程序继续运行其他代码,(我假设是从其他消息启动的,但我仍然找不到关于此主题的好信息,因此,作为本主题的旁白,是否有人有关于此主题的参考),并到达显示对话框的同一点。因此,我最终得到了大量对话框

我的目标是防止对话框数量过多。如果程序到达此对话框起始点,我希望它等待/暂停,直到第一个对话框完成

我考虑过线程解决方案、后台工作人员以及各种各样的想法,但它们似乎使事情变得复杂,而我实际上还没有解决它

有人知道我该如何防止这种情况发生吗

非常感谢你的帮助。
谢谢

我将看到两种可能性: 如果对话框在一个位置打开,则在该位置更改为不调用对话框,而是调用某种堆栈,并且可以检查对话框何时关闭,堆栈上是否有剩余内容

或者,如果可能,在打开第一个对话框时更改传递给该对话框的所有者窗口,并将其隐藏。
如果所有者是隐藏的->对话框是隐藏的。

在我看来,你的代码中有一些非常丑陋的错误!我会首先集中精力修复这个错误。简单的方法是在打开对话框的行上设置断点。当第二次点击该行时(第一个对话框仍然打开),查看该点的堆栈跟踪,并检查所有活动线程(查看线程和查看堆栈窗口)以查找问题的原因

此外,更改代码以打开模式对话框窗口,其中父窗口必须是所有者。模式对话框窗口将停止执行并阻止父窗口处理用户输入(这可能导致此行为)

编辑 从您的评论中,我收集到您有几个无法控制的线程,并且您希望每次有一个线程来访问messagebox代码。使用线程时,有几个同步原语可用。在每个线程上展开需要一本书(你可以尝试一下,虽然这本书的结构有一些缺陷,但这是一本彻底的书),要知道适合你的书需要了解你的代码

这就是说,您可能希望执行以下操作,使用一个至少阻止其他线程访问代码的互斥体(意思是:在释放互斥体之前,它将使其他线程处于挂起状态)。添加一个静态布尔标志变量(或在弹出的表单“仅显示一次”上添加一个复选框)如果要防止弹出框显示多次。Mutex plus标志一次解决了两个问题:只有一个线程将运行该代码,而代码将只运行一次

// as static class variable, create a mutex
private static Mutex dialogMutex = new Mutex();

// a static flag preventing the dialog box to show more than once
// (you may wish to resolve this differently, depending on req's)
private static boolean dialogIsShownOnce = false;

public static void ShowDialogBox()
{
    // Wait until it is safe to enter, this makes the current thread 
    // the exclusive user of this code and other threads may only enter
    // after the current thread finishes.
    dialogMutex.WaitOne();

    // depending on your requirements, you may not want this
    // must come _after_ WaitOne to prevent entering before another
    // thread that entered hasn't yet changed this variable
    if(dialogIsShownOnce)
       return;


    // show your dialog box as a modal box 
    // if you are unsure: add a breakpoint just after the ShowDialog 
    // it should only be hit _after_ you dismiss the dialog box
    yourForm.ShowDialog();

    // set the flag, or the counter, or whatever you wish:
    dialogIsShownOnce = true;

    // Release the Mutex, this will remove the "roadblock" and allow
    // other threads to enter this piece of code
    dialogMutex.ReleaseMutex();
}

上面的代码未经测试,应被视为解决此问题的提示。解决此问题的方法有很多,但我认为上面的方法可能正是您所需要的。

我可能误解了这里的问题,但您是否尝试过以下方法:

 Dim frmFindForm As dlgPromptForm

 frmFindForm = New dlgPromptForm()     

 If (frmFindForm.ShowDialog(Me) = DialogResult.OK) Then
    'Do something because they hit ok, if needed
 Else
    'Do something else because they didn't hit ok, if needed
 End If`
要使其正常工作,您需要确保对话框窗体在用户点击按钮时设置DialogResult属性。(例如:单击“确定”按钮时,DialogResult=System.Windows.Forms.DialogResult.OK)

这将导致程序在if处停止,直到用户按下对话框上的一个按钮

同样,这可能与您要查找的内容不符,但我确实无法从您提供的信息中判断。

使用ShowDialog()不应该让其余的代码在对话框关闭之前执行。因此,我猜您的代码有问题。正如Abel所建议的,您应该使用断点并跟踪代码。 我的另一个猜测是,其他对话框是从原始对话框中启动的,并且它不断递归地发生


如果您在这里发布代码,会更容易提供帮助。

我只需创建一个表单范围

DIM DisplayedMSGBOX为布尔值=false

(如果线程在单独的窗体上运行,只需将此布尔值设为全局)

public DisplayedMSGBOX为布尔值=false)

然后在显示消息框的位置,我将

如果未显示EdmsgBox,则

msgbox(“这将是您的msgbox”)

恩迪夫

如果您想简单地重置msgbox以供再次使用,则在某个时候

DisplayedMSGBOX=false


现在msgbox被重置。

是的,这可能是由您的代码引起的,正如Abel所建议的,但是还有一个非常愚蠢的Visual Studio Designer错误,它也会导致一次单击就打开两个甚至三个对话框

您知道如何在Visual Studio Designer中双击一个元素或按钮,它将在代码中为它创建一个空的子元素(如果没有找到现有代码)?嗯,Visual Studio/Basic中有一个非常恼人的错误,双击一个新按钮(有时)会不创建新的sub,而是在没有您的意愿或同意的情况下,将该按钮的单击事件随机、莫名其妙地钉在现有sub上。如果您不注意并忘记删除垃圾单击事件,您将意外地同时启动多个sub

以下是我参与的一个项目中的一个例子:

Private Sub btnOptionsThemeLB_HK_Click(sender As System.Object, e As System.EventArgs) Handles btnOptionsThemeLB_HK.Click, btnOptionsThemeLB_Back2.Click, btnOptionsThemeLB_Back5.Click, btnOptionsThemeLB_Back4.Click
    ColorMeNow.Color = tempOptionsThemeLB_HK
    ColorMeNow.ShowDialog()
    Me.btnOptionsThemeLB_HK.BackColor = ColorMeNow.Color
    txtbOptionsThemeLB_HK_Red.Text = exRed(ColorMeNow.Color).ToString
    txtbOptionsThemeLB_HK_Green.Text = exGreen(ColorMeNow.Color).ToString
    txtbOptionsThemeLB_HK_Blue.Text = exBlue(ColorMeNow.Color).ToString
    txtbOptionsThemeLB_HK_Hex.Text = exHexFromColor(ColorMeNow.Color)
    tempOptionsThemeLB_HK = ColorMeNow.Color
    'My.Settings.Save()
End Sub
这里的罪犯可以在次级申报行中找到

我本应该:

  Private Sub ... Handles btnOptionsThemeLB_HK.Click
但是,我有:

  Private Sub ... Handles btnOptionsThemeLB_HK.Click, btnOptionsThemeLB_Back2.Click, btnOptionsThemeLB_Back5.Click, btnOptionsThemeLB_Back4.Click
所有这些子组件都打开了颜色选择器对话。Back2、Back4和Back5被附加到子组件上。desi自动单击MELB_HK_