首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >几秒钟后关闭MessageBox

几秒钟后关闭MessageBox
EN

Stack Overflow用户
提问于 2013-01-25 21:14:23
回答 14查看 186.2K关注 0票数 90

我有一个Windows Forms应用程序VS2010 C#,其中我显示了一个用于显示消息的MessageBox。

我有一个if按钮,但如果他们离开了,我想超时并在5秒后关闭消息框,自动关闭消息框。

有一些自定义的MessageBox (从Form继承而来)或另一个报表表单,但它不是必须的表单,这将是很有趣的。

对此有什么建议或示例吗?

更新:

对于WPF

Automatically close messagebox in C#

自定义MessageBox (使用Form inherit)

http://www.codeproject.com/Articles/17253/A-Custom-Message-Box

http://www.codeproject.com/Articles/327212/Custom-Message-Box-in-VC

http://tutplusplus.blogspot.com.es/2010/07/c-tutorial-create-your-own-custom.html

http://medmondson2011.wordpress.com/2010/04/07/easy-to-use-custom-c-message-box-with-a-configurable-checkbox/

可滚动的MessageBox

A Scrollable MessageBox in C#

异常报告程序

https://stackoverflow.com/questions/49224/good-crash-reporting-library-in-c-sharp

http://www.codeproject.com/Articles/6895/A-Reusable-Flexible-Error-Reporting-Framework

解决方案:

也许我认为下面的答案是很好的解决方案,不需要使用表单。

https://stackoverflow.com/a/14522902/206730

https://stackoverflow.com/a/14522952/206730

EN

回答 14

Stack Overflow用户

回答已采纳

发布于 2013-01-25 21:41:45

尝试以下方法:

代码语言:javascript
复制
AutoClosingMessageBox.Show("Text", "Caption", 1000);

其中,AutoClosingMessageBox类按如下方式实现:

代码语言:javascript
复制
public class AutoClosingMessageBox {
    System.Threading.Timer _timeoutTimer;
    string _caption;
    AutoClosingMessageBox(string text, string caption, int timeout) {
        _caption = caption;
        _timeoutTimer = new System.Threading.Timer(OnTimerElapsed,
            null, timeout, System.Threading.Timeout.Infinite);
        using(_timeoutTimer)
            MessageBox.Show(text, caption);
    }
    public static void Show(string text, string caption, int timeout) {
        new AutoClosingMessageBox(text, caption, timeout);
    }
    void OnTimerElapsed(object state) {
        IntPtr mbWnd = FindWindow("#32770", _caption); // lpClassName is #32770 for MessageBox
        if(mbWnd != IntPtr.Zero)
            SendMessage(mbWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
        _timeoutTimer.Dispose();
    }
    const int WM_CLOSE = 0x0010;
    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}

更新:如果你想在用户选择超时之前获得底层MessageBox的返回值,你可以使用以下版本的代码:

代码语言:javascript
复制
var userResult = AutoClosingMessageBox.Show("Yes or No?", "Caption", 1000, MessageBoxButtons.YesNo);
if(userResult == System.Windows.Forms.DialogResult.Yes) { 
    // do something
}
...
public class AutoClosingMessageBox {
    System.Threading.Timer _timeoutTimer;
    string _caption;
    DialogResult _result;
    DialogResult _timerResult;
    AutoClosingMessageBox(string text, string caption, int timeout, MessageBoxButtons buttons = MessageBoxButtons.OK, DialogResult timerResult = DialogResult.None) {
        _caption = caption;
        _timeoutTimer = new System.Threading.Timer(OnTimerElapsed,
            null, timeout, System.Threading.Timeout.Infinite);
        _timerResult = timerResult;
        using(_timeoutTimer)
            _result = MessageBox.Show(text, caption, buttons);
    }
    public static DialogResult Show(string text, string caption, int timeout, MessageBoxButtons buttons = MessageBoxButtons.OK, DialogResult timerResult = DialogResult.None) {
        return new AutoClosingMessageBox(text, caption, timeout, buttons, timerResult)._result;
    }
    void OnTimerElapsed(object state) {
        IntPtr mbWnd = FindWindow("#32770", _caption); // lpClassName is #32770 for MessageBox
        if(mbWnd != IntPtr.Zero)
            SendMessage(mbWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
        _timeoutTimer.Dispose();
        _result = _timerResult;
    }
    const int WM_CLOSE = 0x0010;
    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}

还有另一个更新

我用YesNo按钮检查了@Jack的情况,发现发送WM_CLOSE消息的方法根本不起作用。

我将在单独的AutoclosingMessageBox库的上下文中提供一个修复。这个库包含重新设计的方法,我相信它对某些人是有用的。

它也可以通过NuGet package获得

代码语言:javascript
复制
Install-Package AutoClosingMessageBox

发行说明(v1.0.0.2):

  • 新显示(IWin32Owner)应用编程接口,支持最流行的场景(在#1上下文中);
  • 新工厂()应用编程接口,提供对MessageBox显示的完全控制;
票数 129
EN

Stack Overflow用户

发布于 2014-10-17 13:03:44

在WinForms中工作的解决方案:

代码语言:javascript
复制
var w = new Form() { Size = new Size(0, 0) };
Task.Delay(TimeSpan.FromSeconds(10))
    .ContinueWith((t) => w.Close(), TaskScheduler.FromCurrentSynchronizationContext());

MessageBox.Show(w, message, caption);

基于这样的效果:关闭拥有消息框的窗体也会关闭该框。

Windows窗体控件有一个要求,即必须在创建它们的同一线程上访问它们。假设上面的示例代码是在UI线程或用户创建的线程上执行的,使用TaskScheduler.FromCurrentSynchronizationContext()将确保这一点。如果代码在线程池(例如,计时器回调)或任务池(例如,使用默认参数使用TaskFactory.StartNewTask.Run创建的任务)中的线程上执行,则该示例将无法正常工作。

票数 41
EN

Stack Overflow用户

发布于 2013-01-26 00:08:23

AppActivate!

如果你不介意把你的参考资料弄得乱七八糟,你可以包含Microsoft.Visualbasic,并使用这个非常简单的方法。

显示MessageBox

代码语言:javascript
复制
    (new System.Threading.Thread(CloseIt)).Start();
    MessageBox.Show("HI");

CloseIt函数:

代码语言:javascript
复制
public void CloseIt()
{
    System.Threading.Thread.Sleep(2000);
    Microsoft.VisualBasic.Interaction.AppActivate( 
         System.Diagnostics.Process.GetCurrentProcess().Id);
    System.Windows.Forms.SendKeys.SendWait(" ");
}

现在去洗手吧!

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14522540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档