A common feature of Windows applications for many years has been the useful little “don’t she me this again”-style check boxes that may appear in a dialog box. The Task Dialog API directly supports this feature, too, and as such my WPF Task Dialog Wrapper exposes it as well. Today, I’ll show you how to easily leverage this in a realistic scenario. For more about the wrapper itself, see my article on CodeProject.
The dialog itself only facilitates displaying the check box and text as well as reporting back to you on its checked/unchecked state after the dialog returns (or, optionally, using a TaskDialogCallback
, something I’ll try to cover some other time). Actually implementing the functionality, that is making sure your dialog actually doesn’t show again, is up to you. Fortunately, this is a fairly simple thing to do as I’ll show.
I’m going to use my little ItsBeen app as a demonstration. This is a simple little project of mine, which you can find and download the code to on GitHub here (click on the “Download as zip” button near the top). Out of the box it only uses task dialogs to display fatal exceptions (look in App.xaml.cs near the bottom). There is one other place where it uses them to display a delete confirmation, though. Why don’t we update it to support not displaying the confirmation in the future?
First off, we’ll need some way to store this setting. Since this is a user specific preference, it needs to be stored outside of the main application files. Also, it needs to persist between application runs, which means it’ll need some kind of more permanent storage, such as in a file or database or something.
I like to use a convenient .settings file for this, usually in one named “User.settings”. Here I’ll put all user scoped settings. These have the nice benefit of being stored in a user-specific folder (buried under AppData/LocalSettings for the current user) and in a separately generated, saved, and read file. This satisfies both of our two previously established criteria (but see my “extra credit” section below).
Create the settings file in the ItsBeen.App project. Add a setting named ShowConfirmItemDelete
of type bool
and make sure it’s scope is User. Set it’s value to true
. This way, as you’ll soon see, the confirmation dialog will always show at least the first time.
Now that we have our persistent setting ready, we’ll move on to modifying the confirmation dialog. For those of you following along with my project, open EditItemViewModel.cs and scroll a couple hundred lines down. You should see this block of code:
Now that we have our persistent setting ready, we’ll move on to modifying the confirmation dialog. For those of you following along with my project, open EditItemViewModel.cs and scroll a couple hundred lines down. You should see this block of code:
TaskDialogOptions options = TaskDialogOptions.Default; options.Title = Properties.Resources.ConfirmItemDeleteCaption; options.MainInstruction = String.Format(Properties.Resources.ConfirmItemDeleteContent, _item.Name); options.CommonButtons = TaskDialogCommonButtons.YesNo; _taskDialogService.ShowTaskDialog(this, options, tdResult => { if (tdResult.Result == TaskDialogSimpleResult.Ok || tdResult.Result == TaskDialogSimpleResult.Yes) { DeleteItem(); } });
This sets up a simple task dialog with a basic delete confirmation message. I’ll also note that it is using the TaskDialogService
I covered previously. As such, it defines a simple callback function to check for the confirmation and, if given, deletes the item. (This callback is a feature of the service and should not be confused with the TaskDialogCallback
feature mentioned earlier.)
Let’s modify it to define the verification text, which once set will also cause the checkbox to be displayed. Then we’ll store its checked state value in the user setting defined earlier. We’ll also tweak the logic slightly to skip the confirmation step entirely if need be. All said, the code will now look something like this:
if (Properties.User.Default.ShowConfirmItemDelete) { TaskDialogOptions options = TaskDialogOptions.Default; options.Title = Properties.Resources.ConfirmItemDeleteCaption; options.MainInstruction = String.Format(Properties.Resources.ConfirmItemDeleteContent, _item.Name); options.CommonButtons = TaskDialogCommonButtons.YesNo; options.VerificationText = "Don't show this message again"; _taskDialogService.ShowTaskDialog(this, options, tdResult => { if (tdResult.VerificationChecked.HasValue) Properties.User.Default.ShowConfirmItemDelete = !tdResult.VerificationChecked.Value; if (tdResult.Result == TaskDialogSimpleResult.Ok || tdResult.Result == TaskDialogSimpleResult.Yes) { DeleteItem(); } }); } else { DeleteItem(); }
I’ve wrapped the dialog logic in a conditional check on the show confirmation user setting we made. If it’s turned off, then we immediately delete instead of going through the motions of asking first.
Also note that I set the value of our user setting based on the check box’s checked state before checking the confirmation result and deleting. This way, even if they said no or clicked the cancel X button or something we’ll still capture their show/don’t show preference. I’m also doing a quick null check, just to be safe, since the VerificationChecked
property is a nullable bool
.
And that’s it! If you test it out, you’ll see that indeed we don’t ask to confirm deletes anymore if its checked.
Helpful links:
- Microsoft has some very good advice on Don't show this <item> again
- Here's another bit from Microsoft on it, more specifically from a design concepts point of view
Extra credit: Some of you might notice that the setting is lost when re-running the application! Hey, what gives? I thought that was the whole point of using the settings file? Well, it turns out there’s a bit more work to be done. Your application will need to remember to call Properties.User.Default.Save()
or else the modified values won’t be written to disk. As for how (and when) to do that I leave to you. Personally, I like to put it in an application shutdown event as a quick way to save settings before the application exits.
Side note: For those that were following along with my ItsBeen project code, you’ve probably noticed that adding the User settings file to the ItsBeen.App project causes the ItsBeen.App.Phone project to fail to build. My ItsBeen app demonstrates sharing Model and ViewModel code between two different view systems, WPF and WP7. The App.Phone project is built against the WP7 binaries and framework but uses the same cs files. Unfortunately, WP7 doesn’t support .settings files! Uh oh! Instead, you can drop in the following code to get it to work. But don’t forget my “extra credit” note above: it still applies here!
using System; using System.IO.IsolatedStorage; namespace ItsBeen.App.Properties { internal sealed class User { private static User defaultInstance = new User(); public static User Default { get { return defaultInstance; } } public User() { SetDefaults(); } public bool ShowConfirmItemDelete { get { return ((bool)(IsolatedStorageSettings.ApplicationSettings["ShowConfirmItemDelete"])); } set { IsolatedStorageSettings.ApplicationSettings["ShowConfirmItemDelete"] = value; } } private void SetDefaults() { ShowConfirmItemDelete = true; } } }
No comments:
Post a Comment