Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API Suggestion] Improve MessageBox in WinForms dotnet Core #12044

Open
memoarfaa opened this issue Sep 4, 2024 · 5 comments
Open

[API Suggestion] Improve MessageBox in WinForms dotnet Core #12044

memoarfaa opened this issue Sep 4, 2024 · 5 comments
Labels
api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation

Comments

@memoarfaa
Copy link

Background and motivation

Improving MessageBox is something every developer wants, so they all resort to creating an alternative interface for it. You can find many examples on Github. This is because they cannot localize it or change its appearance, so this new API solves this problem.

Untitledllll

Untitledlast

API Proposal

namespace System.Windows.Forms;

public class MessageBox
{
  /// <summary>
 ///  Type of <see cref="Resources"/> that used to localize Buttons in <see cref="System.Windows.Forms.MessageBox"/>.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static Type? ResourceType { get; set; }
 /// <summary>
 ///  The foreground color of the  <see cref="System.Windows.Forms.MessageBox"/>.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static Color ForeColor { get; set; } = SystemColors.ControlText;
 /// <summary>
 ///  The background color of the  <see cref="System.Windows.Forms.MessageBox"/>.
 /// </summary>

 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static Color BackColor { get; set; } = SystemColors.Window;
 /// <summary>
 ///  The background color of the Footer in <see cref="System.Windows.Forms.MessageBox"/>.
 /// </summary>

 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static Color FooterBackColor { get; set; } = SystemColors.Control;

    /// <summary>
    ///  Sets or gets the MessageBox BorderRadius.
    /// </summary>

    [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
    public MessageBoxCornerPreference MessageBoxBorderRadius{ get;set;}
    /// <summary>
    ///  Sets or gets the MessageBox's border color.
    /// </summary>
   
    public Color MessageBoxBorderColor{ get;set;}
    /// <summary>
    ///  Sets or gets the MessageBox's title bar back color (caption back color).
    /// </summary>
    [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
    public Color MessageBoxCaptionColor{ get;set;}

    /// <summary>
    ///  Sets or gets the MessageBox's title bar text color.
    /// </summary>
    [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
    public Color MessageBoxCaptionTextColor{ get;set;}
}

API Usage

MessageBox.ResourceType = typeof(Properties.Resources)
MessageBox.ForeColor = SystemColors.ControlText;
MessageBox.BackColor = SystemColors.Window;
MessageBox.FooterBackColor = SystemColors.Control;

 MessageBox.Show("MessageBox with Custom Icon", "Custom Icon", MessageBoxButtons.YesNo, SystemIcons.GetStockIcon(StockIconId.Users, StockIconOptions.ShellIconSize));

Alternative Designs

 /// <summary>
 ///  Displays a message box with specified text, caption, style, and custom Icon. with Help Button.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options,
     bool displayHelpButton)
 {
     s_customIcon = icon;
     return ShowCore(null, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, displayHelpButton);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, Help file Path, and custom Icon.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options,
     string helpFilePath)
 {
     HelpInfo hpi = new(helpFilePath);
     s_customIcon = icon;
     return ShowCore(null, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, hpi);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, Help file Path, and custom Icon. for a IWin32Window.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     IWin32Window? owner,
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options,
     string helpFilePath)
 {
     HelpInfo hpi = new(helpFilePath);
     s_customIcon = icon;
     return ShowCore(owner, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, hpi);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, Help file Path, keyword, and custom Icon.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options,
     string helpFilePath,
     string keyword)
 {
     HelpInfo hpi = new(helpFilePath, keyword);
     s_customIcon = icon;
     return ShowCore(null, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, hpi);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, Help file Path, keyword, and custom Icon for a IWin32Window.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     IWin32Window? owner,
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options,
     string helpFilePath,
     string keyword)
 {
     HelpInfo hpi = new(helpFilePath, keyword);
     s_customIcon = icon;
     return ShowCore(owner, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, hpi);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, Help file Path HelpNavigator, and custom Icon.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options,
     string helpFilePath,
     HelpNavigator navigator)
 {
     HelpInfo hpi = new(helpFilePath, navigator);
     s_customIcon = icon;
     return ShowCore(null, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, hpi);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, Help file Path HelpNavigator, and custom Icon for IWin32Window.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     IWin32Window? owner,
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options,
     string helpFilePath,
     HelpNavigator navigator)
 {
     HelpInfo hpi = new(helpFilePath, navigator);
     s_customIcon = icon;
     return ShowCore(owner, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, hpi);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, Help file Path ,HelpNavigator,object and custom Icon.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options,
     string helpFilePath,
     HelpNavigator navigator,
     object? param)
 {
     HelpInfo hpi = new(helpFilePath, navigator, param);
     s_customIcon = icon;
     return ShowCore(null, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, hpi);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, Help file Path ,HelpNavigator, object and custom Icon for a IWin32Window.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     IWin32Window? owner,
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options,
     string helpFilePath,
     HelpNavigator navigator,
     object? param)
 {
     HelpInfo hpi = new(helpFilePath, navigator, param);
     s_customIcon = icon;
     return ShowCore(owner, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, hpi);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, and custom Icon.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton,
     MessageBoxOptions options)
 {
     s_customIcon = icon;
     return ShowCore(null, text, caption, buttons, MessageBoxIcon.Information, defaultButton, options, false);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, and custom Icon.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
     string? text,
     string? caption,
     MessageBoxButtons buttons,
     Icon icon,
     MessageBoxDefaultButton defaultButton)
 {
     s_customIcon = icon;
     return ShowCore(null, text, caption, buttons, MessageBoxIcon.Information, defaultButton, 0, false);
 }

 /// <summary>
 ///  Displays a message box with specified text, caption, style, and custom Icon.
 /// </summary>
 [Experimental(DiagnosticIDs.ExperimentalMessageBox, UrlFormat = DiagnosticIDs.UrlFormat)]
 public static DialogResult Show(
   string? text,
   string? caption,
   MessageBoxButtons buttons,
   Icon icon)
 {
     s_customIcon = icon;
     return ShowCore(null, text, caption, buttons, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, 0, false);
 }

Risks

No response

Will this feature affect UI controls?

Will VS Designer need to support the feature? no
Will this feature need to be localized or be localizable? yes

@memoarfaa memoarfaa added api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation untriaged The team needs to look at this issue in the next triage labels Sep 4, 2024
@merriemcgaw
Copy link
Member

@memoarfaa in .NET 5 we added support for the OS TaskDialog which allows for lots of customization. I think that's the direction we would rather developers go.

@Olina-Zhang @LeafShi1 can you verify for me that TaskDialog API is able to respond to OS dark mode?

@memoarfaa
Copy link
Author

memoarfaa commented Sep 5, 2024

@memoarfaa in .NET 5 we added support for the OS TaskDialog which allows for lots of customization.

@merriemcgaw
Yes that is true but each has its own use
If I need a lot of customization I use TaskDialog otherwise I use MessageBox
1- Can I use TaskDialog to display a simple message withowt extra coding.
For example, I want to display a simple message to tell the user that the database login failed.

 private void CheckConnectionStatus()
 {
     try
     {
         if (_sqlConnection.State != ConnectionState.Open)
         {
             _sqlConnection.Open();
         }

     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.ToString(), "Failed to Open Connection");
     }
 }

This is not about OS dark mode only.
But the question is Winforms has a way to show simple message that can be localized and color without extra coding?

I saw a similar issue still open in Wpf.
dotnet/wpf#5967
Most opinions say that Messagebox in winForms is better than Wpf because it has manifest. In fact they don't need manifest or CreateActCtx to make Messagebox better.

Why don't we make Messagebox much better?

About TaskDialog @Olina-Zhang @LeafShi1
can you verify for that we can change the background and foreground color ?

Is there a problem, if both Messagebox and TaskDialog have a more flexible look?

I will open a pull request for doing this if the team agrees otherwise I will close this issue as not acceptable api.

@Olina-Zhang
Copy link
Member

@Olina-Zhang @LeafShi1 can you verify for me that TaskDialog API is able to respond to OS dark mode?

Setting OS with dark mode color cannot respond to a series of TaskDialogs, although enabled DarkMode for application by Application.SetColorMode(SystemColorMode.Dark)

testdarkmode.mp4

@merriemcgaw
Copy link
Member

The team's consensus is that we try to minimize touching the MessageBox as much as possible. That said, we believe that DarkMode support would be neat for it. Just not actual styling - that should go to the TaskDialog.

@Olina-Zhang can you file a separate issue about TaskDialog not responding to DarkMode?

@merriemcgaw merriemcgaw removed the untriaged The team needs to look at this issue in the next triage label Sep 5, 2024
@Olina-Zhang
Copy link
Member

Filed an issue for TaskDialog not responding to DarkMode: #12062.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion (1) Early API idea and discussion, it is NOT ready for implementation
Projects
None yet
Development

No branches or pull requests

3 participants