Introduction
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.
Background
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 CheckBox
:
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 AutoCloseResult
property.
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 AutoCloseResult
s 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.
The 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 BrowsableAttribute
to false
).
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
The 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 Target
form.
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... .
History
- 21.07.2007 - First release.