When you have to ask the user of your application a question, it is usually done by showing a dialog where the user can answer your question by clicking a button. If this question occurs only once in a while, you can probably skip this article. But if the question occurs rather frequently, and they always have the same answer, users will get annoyed after dismissing the same dialog for the nth time (with n >= 2 and varying with the user). Then, it's time to add a feature to the dialog that allows the user to skip the dialog in the future.
This article describes a control that can add this feature to a dialog.
The idea behind this article is to create a control that simplifies the whole "don't show this dialog again" topic as much as possible, so that the developer using this control can quickly add the control without having to do a lot of configuration.
How to approach the problem
There are two possible locations to address the problem: wither the place where the dialog to be shown is instantiated and actually shown (or not being shown if the user has clicked "don't show..." before), or inside the dialog itself with a little trick (more on this below).
I went for the second option because then the caller of the dialog doesn't have to care whether the dialog does or doesn't have a "don't show..." feature. The dialog is created and shown in exactly the same way, nothing has to be changed.
The way to implement the feature is to create a control that inherits from
That way, you can simply drop the
DontShowAgainCheckBox on your dialog, adjust the text you want it to show, and that's it. The control handles everything else.
Internally, the control cannot really prevent the dialog from being shown - the caller still uses
ShowDialog() to show the dialog, but the
DontShowAgainCheckBox immediately closes the dialog as soon as it's being displayed and returns a given
DialogResult: the value of its
This approach has a little flaw, though. The command to close the dialog is uttered in the
Load event handler of the form. This means that the dialog is visible for a little moment before disappearing again. Although it doesn't have an effect on the functionality itself (the dialog is gone without user interaction), this flicker destroys the illusion of the dialog really not being shown. The solution for this is to set the dialog's
Opacity to 0 before doing anything else. The dialog still appears for a fraction of a second, but because it's completely transparent, you cannot see it - the illusion is kept intact .
If you want to get the same
AutoCloseResult every time the dialog is closed automatically, you only have to set the
AutoCloseResult once using the designer. If you want to get different
AutoCloseResults depending on the button the user clicked for dismissing the dialog, you can easily set the property in the corresponding button event handlers. The demo project shows how to do this.
Target property holds a reference to the dialog the control is on so that the necessary event handler for the
Load event can be wired. Usually, you don't have to set the
Target property yourself. It's being assigned automatically when the control is assigned to a new parent. Because of this, I made the
Target property not browsable (by setting the
In case you want to reset the user's choice to dismiss a dialog forever, there's the static method
Reset(). By giving it an instance of the dialog to reset, the flag that prevents the dialog from being shown is reset.
Points of interest
DontShowAgainCheckBox has to remember which dialog(s) to auto-close. I chose the Registry to store this information, but you could just as well modify the code to use a file, for example.
For every dialog, a different Registry path is used (under HKEY_CURRENT_USER), built according to this pattern:
SOFTWARE\CompanyName\ProductName\DontShowAgainSettings\Form Type\Form Title
CompanyName and ProductName are taken from the corresponding properties of
Application. Form Type is the complete type name of the
Target form (including the namespace). Form Title is the value of the
Text property of the
I didn't stop at the form class name because I wanted to be able to differentiate between two different uses of the same dialog class.
Sometimes, a dialog class can be configured to perform different tasks so that you don't have to implement a new dialog class. If you change the dialog title in this case, the
DontShowAgainCheckBox can keep a different status for both versions. I've included an example for this in the demo project as well.
If you have any suggestions for improvements, please leave a comment. And, don't forget to vote... .
- 21.07.2007 - First release.