Kiq*_*net 72 c# messagebox winforms
我有一个Windows窗体应用程序VS2010 C#,其中我显示一个MessageBox来显示一条消息.
我有一个好的按钮,但如果他们走开,我想超时并关闭消息框后,让我们说5秒,自动关闭消息框.
有自定义的MessageBox(继承自Form)或其他报告者表单,但有趣的是没有必要的Form.
关于它的任何建议或样品?
更新:
对于WPF
在C#中自动关闭消息框
自定义MessageBox(使用表单继承)
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
C#中的可滚动MessageBox
例外记者
/sf/ask/3445711/
http://www.codeproject.com/Articles/6895/A-Reusable-Flexible-Error-Reporting-Framework
解:
也许我认为以下答案是很好的解决方案,而不使用表格.
Dmi*_*ryG 117
尝试以下方法:
AutoClosingMessageBox.Show("Text", "Caption", 1000);
Run Code Online (Sandbox Code Playgroud)
当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);
}
Run Code Online (Sandbox Code Playgroud)
更新: 如果要在超时之前选择某些内容时获取基础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);
}
Run Code Online (Sandbox Code Playgroud)
又一次更新
我用YesNo
按钮检查了@ Jack的案例,发现发送WM_CLOSE
消息的方法根本不起作用.
我将在单独的AutoclosingMessageBox库的上下文中提供修复.这个库包含重新设计的方法,我相信,对某人有用.
它也可以通过NuGet包获得:
Install-Package AutoClosingMessageBox
Run Code Online (Sandbox Code Playgroud)
发行说明(v1.0.0.2):
- 新的Show(IWin32Owner)API,支持大多数流行的场景(在#1的上下文中);
- 新的Factory()API,提供对MessageBox显示的完全控制;
BSh*_*arp 24
一个适用于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);
Run Code Online (Sandbox Code Playgroud)
基于关闭拥有消息框的表单的效果也将关闭该框.
Windows窗体控件要求必须在创建它们的同一线程上访问它们.TaskScheduler.FromCurrentSynchronizationContext()
假设上面的示例代码在UI线程或用户创建的线程上执行,使用将确保.如果代码在线程池(例如计时器回调)或任务池(例如,使用TaskFactory.StartNew
或Task.Run
使用默认参数创建的任务)上执行,则该示例将无法正常工作.
Fas*_*tAl 16
如果你不介意稍微弄清楚你的参考文献,你可以包括Microsoft.Visualbasic,
并使用这个非常简短的方法.
显示MessageBox
(new System.Threading.Thread(CloseIt)).Start();
MessageBox.Show("HI");
Run Code Online (Sandbox Code Playgroud)
CloseIt功能:
public void CloseIt()
{
System.Threading.Thread.Sleep(2000);
Microsoft.VisualBasic.Interaction.AppActivate(
System.Diagnostics.Process.GetCurrentProcess().Id);
System.Windows.Forms.SendKeys.SendWait(" ");
}
Run Code Online (Sandbox Code Playgroud)
现在去洗手!
Esg*_*sge 11
System.Windows.MessageBox.Show()方法有一个重载,它将所有者Window作为第一个参数.如果我们创建一个不可见的所有者窗口,然后我们在指定的时间后关闭它,它的子消息框也会关闭.
Window owner = CreateAutoCloseWindow(dialogTimeout);
MessageBoxResult result = MessageBox.Show(owner, ...
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是,如果UI线程被消息框阻止,并且无法从工作线程访问UI控件,我们如何关闭窗口?答案是 - 通过向所有者窗口句柄发送WM_CLOSE窗口消息:
Window CreateAutoCloseWindow(TimeSpan timeout)
{
Window window = new Window()
{
WindowStyle = WindowStyle.None,
WindowState = System.Windows.WindowState.Maximized,
Background = System.Windows.Media.Brushes.Transparent,
AllowsTransparency = true,
ShowInTaskbar = false,
ShowActivated = true,
Topmost = true
};
window.Show();
IntPtr handle = new WindowInteropHelper(window).Handle;
Task.Delay((int)timeout.TotalMilliseconds).ContinueWith(
t => NativeMethods.SendMessage(handle, 0x10 /*WM_CLOSE*/, IntPtr.Zero, IntPtr.Zero));
return window;
}
Run Code Online (Sandbox Code Playgroud)
这是SendMessage Windows API方法的导入:
static class NativeMethods
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}
Run Code Online (Sandbox Code Playgroud)
Jen*_*und 10
你可以试试这个:
[DllImport("user32.dll", EntryPoint="FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.Dll")]
static extern int PostMessage(IntPtr hWnd, UInt32 msg, int wParam, int lParam);
private const UInt32 WM_CLOSE = 0x0010;
public void ShowAutoClosingMessageBox(string message, string caption)
{
var timer = new System.Timers.Timer(5000) { AutoReset = false };
timer.Elapsed += delegate
{
IntPtr hWnd = FindWindowByCaption(IntPtr.Zero, caption);
if (hWnd.ToInt32() != 0) PostMessage(hWnd, WM_CLOSE, 0, 0);
};
timer.Enabled = true;
MessageBox.Show(message, caption);
}
Run Code Online (Sandbox Code Playgroud)
我知道这个问题已经有 8 年历史了,但是过去和现在都有一个更好的解决方案。它一直都在那里,而且仍然是:MessageBoxTimeout()
在 中User32.dll
。
这是 Microsoft Windows 使用的一个未记录的函数,它完全可以满足您的需求,甚至更多。它也支持不同的语言。
C# 导入:
[DllImport("user32.dll", SetLastError = true)]
public static extern int MessageBoxTimeout(IntPtr hWnd, String lpText, String lpCaption, uint uType, Int16 wLanguageId, Int32 dwMilliseconds);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetForegroundWindow();
Run Code Online (Sandbox Code Playgroud)
如何在 C# 中使用它:
uint uiFlags = /*MB_OK*/ 0x00000000 | /*MB_SETFOREGROUND*/ 0x00010000 | /*MB_SYSTEMMODAL*/ 0x00001000 | /*MB_ICONEXCLAMATION*/ 0x00000030;
NativeFunctions.MessageBoxTimeout(NativeFunctions.GetForegroundWindow(), $"Kitty", $"Hello", uiFlags, 0, 5000);
Run Code Online (Sandbox Code Playgroud)
更聪明地工作,而不是更努力地工作。
CodeProject 的 RogerB对这个答案提出了最巧妙的解决方案之一,他在 04 年就这样做了,现在仍然很成功
基本上,您到这里访问他的项目并下载 CS 文件。万一该链接失效,我在这里有一个备份要点。将 CS 文件添加到您的项目中,或者如果您愿意,可以将代码复制/粘贴到某处。
然后,你所要做的就是切换
DialogResult result = MessageBox.Show("Text","Title", MessageBoxButtons.CHOICE)
Run Code Online (Sandbox Code Playgroud)
到
DialogResult result = MessageBoxEx.Show("Text","Title", MessageBoxButtons.CHOICE, timer_ms)
Run Code Online (Sandbox Code Playgroud)
你很高兴去。
归档时间: |
|
查看次数: |
143719 次 |
最近记录: |