我有一个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
可滚动的MessageBox
异常报告程序
https://stackoverflow.com/questions/49224/good-crash-reporting-library-in-c-sharp
http://www.codeproject.com/Articles/6895/A-Reusable-Flexible-Error-Reporting-Framework
解决方案:
也许我认为下面的答案是很好的解决方案,不需要使用表单。
发布于 2013-01-25 21:41:45
尝试以下方法:
AutoClosingMessageBox.Show("Text", "Caption", 1000);
其中,AutoClosingMessageBox
类按如下方式实现:
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的返回值,你可以使用以下版本的代码:
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获得
Install-Package AutoClosingMessageBox
发行说明(v1.0.0.2):
发布于 2014-10-17 13:03:44
在WinForms中工作的解决方案:
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.StartNew
或Task.Run
创建的任务)中的线程上执行,则该示例将无法正常工作。
发布于 2013-01-26 00:08:23
AppActivate!
如果你不介意把你的参考资料弄得乱七八糟,你可以包含Microsoft.Visualbasic,
并使用这个非常简单的方法。
显示MessageBox
(new System.Threading.Thread(CloseIt)).Start();
MessageBox.Show("HI");
CloseIt函数:
public void CloseIt()
{
System.Threading.Thread.Sleep(2000);
Microsoft.VisualBasic.Interaction.AppActivate(
System.Diagnostics.Process.GetCurrentProcess().Id);
System.Windows.Forms.SendKeys.SendWait(" ");
}
现在去洗手吧!
https://stackoverflow.com/questions/14522540
复制相似问题