打开MessageBox的多个实例,并在几秒钟后自动关闭

时间:2014-02-04 15:05:52

标签: c# winforms timer messagebox auto-close

我正在使用Visual Studio 2012在C#中编写Windows窗体,我想在几秒钟之后打开MessageBox的多个实例自动关闭它们

我在这里找到(并赞成)这个答案:SO: Close a MessageBox after several seconds

然而,如果我一次只打开1(一个)MessageBox,这是有效的,因为它使用了函数FindWindow,而我的MessageBox的多个实例将具有所有相同的窗口标题(标题)

[可选] 此外,我想向用户显示倒计时,例如此对话框将在5秒后关闭此[.. 。]在4秒内这[...]在3秒内,...,这[...]在1秒内然后终于关闭MessageBox。

有没有办法独特地引用我的多个MessageBox并自动关闭它们(使用System.Timers.TimerSystem.Threading.TimerSystem.Windows.Forms.Timer - 最适合此解决方案的一个)一段时间(比如5秒)?

3 个答案:

答案 0 :(得分:4)

我建议不要使用MessageBox来执行此任务。相反,制作自己的自定义表单。使它成为你想要的尺寸,形状和外观。然后,在其代码隐藏文件中,您可以创建一个对该窗口本身唯一的计时器。这样,您可以根据需要生成尽可能多的计时器,并且他们将管理自己的计时器并自行关闭,而您无需执行任何操作,例如查找窗口。可以使Form看起来非常像MessageBox。因为你可以调用ShowDialog,你可以使它们的行为与MessageBoxes类似(虽然这会产生一定的反作用,因为你一次只能与一个对话框进行交互)。

答案 1 :(得分:1)

Windows中有一个未记录的MessageBoxTimeout函数可以使用:user32.dll中的MessageBoxTimeout(通过PInvoke使用)。

示例:

public class MessageBoxWithTimeout
{
  [DllImport("user32.dll", SetLastError = true)]
  [return: MarshalAs(UnmanagedType.U4)]
  private static extern uint MessageBoxTimeout(IntPtr hwnd,
    [MarshalAs(UnmanagedType.LPTStr)]  String text,
    [MarshalAs(UnmanagedType.LPTStr)] String title,
    [MarshalAs(UnmanagedType.U4)] uint type, 
    Int16 wLanguageId, 
    Int32 milliseconds);

  public static uint Show(IntPtr hWnd, string message, string caption, uint messageBoxOptions,Int32 timeOutMilliSeconds)
  {
     return MessageBoxTimeout(hWnd, message, caption, messageBoxOptions, 0, timeOutMilliSeconds);
  }
}

在您的代码中:

MessageBoxWithTimeout.Show( your parameters here );

但是,你应该考虑一下你的设计。根据定义,消息框会阻止您的对话框,因此多个消息框没有意义。如果您发布实际问题,可能有更好的解决方案。

答案 2 :(得分:1)

以下代码可用作起点。它基于我最近给出的related answer

async void MainForm_Load(object sender, EventArgs e)
{
    Func<Func<Form>, Task<Form>> showAsync = (createForm) =>
    {
        var tcs = new TaskCompletionSource<Form>();
        var form = createForm();
        form.Tag = Task.Factory.StartNew(
            () => form.ShowDialog(), 
            CancellationToken.None, 
            TaskCreationOptions.None,
            TaskScheduler.FromCurrentSynchronizationContext());
        form.Load += (sIgnore, eIgnore) =>
            tcs.TrySetResult(form);
        return tcs.Task;
    };

    var forms = new Stack<Form>();
    for (var i = 0; i < 4; i++)
        forms.Push(await showAsync((() =>
            new Form { Text = "Hello #" + i })));

    var closeFormTasks = forms.Select((form) => (Task)form.Tag);

    var delay = Task.Delay(5000);
    var task = await Task.WhenAny(delay, Task.WhenAll(closeFormTasks));

    if (task == delay)
    {
        while (forms.Any())
        {
            var form = forms.Pop();
            form.Close();
            await (Task)form.Tag;
        }
    }

    MessageBox.Show("All closed.");
}