WinForms - How to Allow Users to Skip Messages

WinForms Team Blog
03 April 2020

It’s an unbelievably difficult time – we do hope everyone is doing well and making the best out of present circumstances. If we can be of help, please don’t hesitate to reach out (clientservices@devexpress.com). A big shout-out to all the brilliant scientists throughout the world focused on a vaccine/cure...Thank you for your hard work.


Each time our team implements a new feature, we do our best to describe its capabilities. In our zeal to document popular controls such as our WinForms Data Grid, we often fail to articulate the power and flexibility of the utility controls included in our WinForms Subscription.

Message Boxes are a perfect example of high-value utility controls within our WinForms product portfolio. Since most applications communicate with users via message boxes, I thought it’s time we described our WinForms Message Box controls in greater detail and show you what we have in store in our upcoming release (v20.1).

DevExpress XtraMessageBox objects are counterparts to default WinForms messages. At first glance, the primary advantage of XtraMessageBox lies in its ability to use DevExpress application skins. Though this is an important advantage (after all, who wants to display standard gray-ish messages within a fully themed WinForms application), it is by no means the only strength of XtraMessageBox.

While you can display a message using a standard approach (pass text strings and a button set into a static XtraMessageBox.Show() method overload), you can also create an XtraMessageBoxArgs object and pass it as the only Show method parameter. As you might expect, this object allows you to incorporate additional behavior. For example, you can display messages that automatically close when an embedded timer expires.

XtraMessageBoxArgs args = new XtraMessageBoxArgs();
args.AutoCloseOptions.Delay = 5000;
args.Caption = "Auto-close message";
args.Text = "This message closes automatically after 5 seconds.";
args.Buttons = new DialogResult[] { DialogResult.OK, DialogResult.Cancel };
//show a countdown on a default button
args.AutoCloseOptions.ShowTimerOnDefaultButton = true;
XtraMessageBox.Show(args);

The XtraMessageBoxArgs.Showing event allows you to access and modify a message form before it is displayed on-screen. You can use this for all sorts of things. For instance, to limit message width...

XtraMessageBoxArgs args = new XtraMessageBoxArgs();
args.Caption = "A very long message";
args.Text = "A message box attempts to show all of its text content in one line. " +
    "If you do not limit the form size, this message will be very long and thin. " +
    "Set the maximum form width and the form will wrap this long text.";
args.Buttons = new DialogResult[] { DialogResult.OK, DialogResult.Cancel};
args.Showing += Args_Showing;
XtraMessageBox.Show(args);

private void Args_Showing(object sender, XtraMessageShowingArgs e)
{
    e.Form.MaximumSize = new Size(600, 600);
}

...or customize message buttons (change captions or supply them with vector images).

XtraMessageBoxArgs args = new XtraMessageBoxArgs();
args.Caption = "A message with icons";
args.Text = "This message displays custom SVG images in its buttons";
args.Buttons = new DialogResult[] {
    DialogResult.OK, DialogResult.Cancel, DialogResult.Retry };
args.Showing += Args_Showing;
XtraMessageBox.Show(args);

void Args_Showing(object sender, XtraMessageShowingArgs e) {
    foreach (var control in e.Form.Controls)
    {
        SimpleButton button = control as SimpleButton;
        if (button != null)
        {
            button.ImageOptions.SvgImageSize = new Size(16, 16);
            button.ImageOptions.ImageToTextAlignment = ImageAlignToText.LeftCenter;
            //button.Height = 25;
            switch (button.DialogResult)
            {
                case (DialogResult.OK):
                    button.ImageOptions.SvgImage = svgImageCollection1[0];
                    break;
                case (DialogResult.Cancel):
                    button.ImageOptions.SvgImage = svgImageCollection1[1];
                    break;
                case (DialogResult.Retry):
                    button.ImageOptions.SvgImage = svgImageCollection1[2];
                    break;
            }
        }
    }
}

With v20.1, you will be able to easily include a "Do not show this message again" checkbox into your messages. If you’d like to incorporate this capability in your project, simply set the Boolean XtraMessageBoxArgs.DoNotShowAgainCheckBoxVisible property to true. And yes, the checkbox text is also customizable.

XtraMessageBoxArgs args = new XtraMessageBoxArgs();
args.Caption = "Message";
args.Text = "You are using a trial version. The trial period expires in 30 days";
args.DoNotShowAgainCheckBoxVisible = true;
args.DoNotShowAgainCheckBoxText = "Do not remind me again";
XtraMessageBox.Show(args);

This checkbox does not do anything itself. When the message appears on-screen (or is dismissed), it raises Load and Closed events. You need to handle these events to store and retrieve e.Visible property value. This property value specifies whether a user chose to suppress the message. If Load event arguments receive false for the e.Visible property value, the message is canceled.

args.Load += Args_Load;
args.Closed += Args_Closed;

void Args_Closed(object sender, XtraMessageBoxClosedArgs e) {
    //save e.Visible to a database or a local storage file
}

void Args_Load(object sender, XtraMessageBoxLoadArgs e) {
    //retireve the value from a database or a local storage file
    e.Visible = value;
}

Along with e.Visible, you can also store the e.DialogResult property value. It corresponds to the last known DialogResult used when the message was closed. If a message was suppressed, you can use this value so that the Show method returns the last user choice instead of DialogResult.None.

void Args_Load(object sender, XtraMessageBoxLoadArgs e) {
    e.Visible = _restoredVisibleValue_;
    if (!e.Visible)
    {
        //restore the e.DialogResult property
        e.DialogResult = _restoredDialogResultValue_;
    }
}

For those who do not want to manually save and restore these parameters, we give you the option to store them in the registry. To that, call the SaveToRegistry method on the Closed event, and RestoreFromRegistry on Load.

void Args_Closed(object sender, XtraMessageBoxClosedArgs e) {
    e.SaveToRegistry();
}

void Args_Load(object sender, XtraMessageBoxLoadArgs e) {
    e.RestoreFromRegistry();
}

This code saves DialogResult and Visible keys under the Computer\HKEY_CURRENT_USER\Software\X\Y path, where:

  • X - value of the XtraMessageBox.RegistryPath property, or Path.Combine(Application.CompanyName, Application.ProductName, "Messages") if the property is not set;
  • Y - value of the XtraMessageBoxArgs.RegistryKey property, or an automatically generated ID.

Last but not least, you can forcibly display a message even when a user has chosen to hide it. To do that, call the e.ShowMessage method in the Load event handler. The boolean method parameter specifies whether the "Do not show again" checkbox should be checked.

XtraMessageBoxArgs args;
int trialDaysLeft;
//...
args = new XtraMessageBoxArgs();
args.Caption = "Message";
args.Text = "You are using a trial version. The trial period expires in " +
    trialDaysLeft.ToString() + " days.";
args.DoNotShowAgainCheckBoxVisible = true;
args.RegistryPath = "MyTestApp";
args.RegistryKey = "ShowTrialDaysLeftMessage";
args.Load += Args_Load;
args.Closed += Args_Closed;

void Args_Closed(object sender, XtraMessageBoxClosedArgs e) {
    e.SaveToRegistry();
}

void Args_Load(object sender, XtraMessageBoxLoadArgs e) {
    e.RestoreFromRegistry();
    if (!e.Visible && trialDaysLeft < 3) {
        e.MessageBoxArgs.Text =
            "Your trial expires in " + trialDaysLeft.ToString() + " day(s)!";
        e.MessageBoxArgs.DoNotShowAgainCheckBoxVisible = false;
        e.ShowMessage(false);
    }
}

Showcase Your Apps on DevExpress.com

Highlight your business app and share your development experiences with the DevExpress community. To include your app in our upcoming App Showcase, please forward an application screenshot to clientservices@devexpress.com and tell us which DevExpress products you currently use within your organization.
13 comment(s)
renejdm
renejdm
Thank you for this very powerful control.
3 April 2020
Del W
Del W

This looks great, Thanks!

Stay Safe


3 April 2020
dbSoft
dbSoft
I will defenately use the 'not show this message again property'! Very clever approach! It whould be nice if you could provide us a property, in how many days we want show dialog again.
3 April 2020
Tamás
Tamás

Thank you, these are very good improvements!

In the new version, it will be possible to display image in html formatted text? (XtraMessageBox text)

Unfortunately in previous versions this did not work at all. :(

Thanks!

4 April 2020
Christopher Jay
Christopher Jay
Great improvements, but I also would like to know if HTML formatting will be possible like it is with the current dialog box.  Thanks!
4 April 2020
Cyber Sinh
Cyber Sinh
Any plan for a WPF message box control?
5 April 2020
Brendon Muck [DevExpress MVP]
Brendon Muck [DevExpress MVP]

Are you looking for the DXMessageBox class?

https://docs.devexpress.com/WPF/DevExpress.Xpf.Core.DXMessageBox

5 April 2020
Edhy Rijo
Edhy Rijo

Awesome, very cool and useful enhancements to the XtraMessageBox.

I definitely will use them all.

Thanks a lot for keep up with new features.

 

5 April 2020
Cyber Sinh
Cyber Sinh
WPF ThemedMessageBox has not all features of WinForms XtraMessageBox.
6 April 2020
Lluis Franco
Lluis Franco

Great! :D

It'd be nice to set the backcolor too:

button.BackColor = DXSkinColors.FillColors.Success;

 




6 April 2020
Dmitry (DevExpress)
Dmitry (DevExpress)

@Lluis Franco

I was wondering if the article says you can access buttons to set up their images, why cannot one change background colors as well? So I took a sample from the article and modified it a little:

switch (button.DialogResult)
{
    case (DialogResult.OK):
        button.Appearance.BackColor = DXSkinColors.FillColors.Success;
        break;
    case (DialogResult.Cancel):
        button.Appearance.BackColor = DXSkinColors.FillColors.Warning;
        break;
    case (DialogResult.Retry):
        button.Appearance.BackColor = DXSkinColors.FillColors.Question;
        break;
}

Turns out, it works out perfectly fine. Try this out, is that what you requested?

6 April 2020
Dmitry (DevExpress)
Dmitry (DevExpress)

@Tamás

In the new version, it will be possible to display image in html formatted text? (XtraMessageBox text)


We gave it a thought and it's a very reasonable request indeed. So we've pulled a few strings, wrote a few code lines here and there, and the upcoming beta will now include the functionality you're asking for.

XtraMessageBoxArgs args = new XtraMessageBoxArgs();
args.AllowHtmlText = DevExpress.Utils.DefaultBoolean.True;
args.HtmlImages = htmlImageCollection;
args.Caption = "Message";
args.Text = "<image=img.png>Text<image=#imgResourceName>";
XtraMessageBox.Show(args);

Thank you for the valuable suggestion!

7 April 2020
Tamás
Tamás

Dear Dmitry,

thanks for the development (image in html formatted text), it will come in very handy, I look forward to trying it out!

Best regards,

Tamas


7 April 2020

Please login or register to post comments.