This request is based on popular SO question: Close a MessageBox after several seconds (100+ votes).
When developing LOB application it is quite often needed to interact with the user via the MessageBox which automatically closes after the specific timeout. The standard MessageBox.Show API does not provide this capability.
The new API should be based on standard Win32 MessageBox and should be compatible with corresponding .Net implementation (System.Windows.Forms.MessageBox).
The AutoClosingMessageBox repository contains a good example of WinAPI-based wrapper on standard Win32 MessageBox compatible with the .Net System.Windows.Forms.MessageBox.
Here how you can use the new API:
Scenario 1: Fire and forget - it about to be closed after default timeout(1000ms)
```c#
AutoClosingMessageBox.Show("Hello, you are using the AutoClosingMessageBox first time!");
Scenario 2: Wait for some result or make the default decision
```c#
var result = AutoClosingMessageBox.Show(
text: "To be or not to be?",
caption: "The question",
timeout: 2500,
buttons: MessageBoxButtons.YesNo,
defaultResult: DialogResult.Yes);
if(result == DialogResult.Yes) {
// to be
}
else {
// or not
}
Additionaly you can use the AutoClosingMessageBox.Factory method to wrap the specific MessageBox showing. This way allows us do not provide all the AutoClosingMessageBox.Show method overloads which associated with the corresponting System.Windows.Forms.MessageBox.Show methods.
```c#
var toBeOrNotToBeQuestion = AutoClosingMessageBox.Factory(
showMethod: (caption, buttons) =>
MessageBox.Show(this, "To be or not to be?", caption, buttons, MessageBoxIcon.Question),
caption: "The question"
);
if(DialogResult.Yes == toBeOrNotToBeQuestion.Show(
timeout: 2500,
buttons: MessageBoxButtons.YesNo,
defaultResult: DialogResult.Yes)) {
// to be
}
else {
// or not
}
### Proposed API:
```c#
public static class AutoClosingMessageBox {
public static DialogResult Show(string text, string caption = null, int timeoutMilliseconds = 1000, MessageBoxButtons buttons = MessageBoxButtons.OK, DialogResult defaultResult = DialogResult.None);
public static DialogResult Show(IWin32Window owner, string text, string caption = null, int timeoutMilliseconds = 1000, MessageBoxButtons buttons = MessageBoxButtons.OK, DialogResult defaultResult = DialogResult.None);
}
The AutoClosingMessageBox.Factory method (optional, but suggested):
c#
public static class AutoClosingMessageBox {
public static IAutoClosingMessageBox Factory(Func<string, MessageBoxButtons, DialogResult> showMethod, string caption = null);
//
public interface IAutoClosingMessageBox {
DialogResult Show(int timeoutMilliseconds = 1000, MessageBoxButtons buttons = MessageBoxButtons.OK, DialogResult defaultResult = DialogResult.None);
}
}
Thanks for the suggestion! Could you follow the API Review Process to move this along? In the meantime I will move this to the future milestone.
馃挕 I would suggest using TimeSpan instead of int for the timeout.
Why it should be separate AutoClosingMessageBox class? Why it can't be just extra optional parameter on MessageBox calss?
Also, it looks like we require to add extra state to DialogResult to specify that mbox was closed automatically.
@sharwell
Thanks for participating, Sam.
Initially, the timeout parameter was designed according to the widely used Task.Delay(1000) pattern.
Using the TimeSpan do not allow us to make the timeout parameter optional because we can't specify the default value TimeSpan.FromMilliseconds(1000) (not a compile-time constant).
BTW, I have renamed the parameter timeout to the timeoutMilliseconds in the proposal.
@euroUK
Thanks for participating, Yury.
There are two important reasons for dot not touching the default MessageBox API:
At first, because of potential breaking changes.
From my experience, it is often needed to create reflection-based proxies for the standard MessageBox API in order to create cross-platform UI libraries or frameworks which provide some level of abstraction.
Another reason is following the modern and simple API concepts .
The MessageBox API is created for the framework version which does not provide the optional arguments. As result, we have now over 20 overloads for Show method. Extending this overloads with additional parameter requires to add yet another 20 overloads...
With separate AutoClosingMessageBox class (of course its final name should be discussed) we can use simplified API for popular scenarios(Show method) and special API (Factory method) which allows wrapping any specific call of legacy MessageBox.Show method. You can see the example in my proposal.
Regarding the extra state for DialogResult, I do not think that is really needed because we control this result via the defaultResult optional parameter.
We can't modify MessageBox API. However you can achieve auto-closing (manual or automated) functionality using TaskDialog API.
@RussKie
Hi Igor! Thanks for participating.
We can't modify
MessageBoxAPI.
I have never talked about modifying the MessageBox API. Please read my proposal and arguments carefully)
you can achieve auto-closing (manual or automated) functionality
Sure, I have already achieved the required functionality years ago with using quite simple code.
However, it's time to upgrade the resulting lib onto the latest official .net core version, thanks for the reminder)
I have never talked about modifying the MessageBox API. Please read my proposal and arguments carefully)
I appreciate it.
However Windows Forms is a wrapper for Win32 controls to allow faster and simpler development of native Windows apps. Adding a completely custom functionality is not really on our roadmap, 3rd party libraries are better suited for that.
And by providing the Task Dialog API we have provided a way to achieve the desired functionality, this is why I closed your proposal.
Most helpful comment
馃挕 I would suggest using
TimeSpaninstead ofintfor the timeout.