views:

255

answers:

2

What is the best way to implement a "program options" dialog with the "Reset to default" capability in C# (vs2005)?

Below is the way I am doing.

  1. Create a dialog form and add some controls (like checkBoxes) to it. Also add three buttons: Ok, Cancel, Default.
  2. Create Settings file and add some fields in the user scope.
  3. Bind the dialog controls with the corresponding settings fields through the "Application Settings" properties in the Visual Studio property dialog.
  4. Add some code to the owner form:

    if (myDialog.ShowDialog(this) == DialogResult.OK)
    {
    MySettings.Default.Save();
    }
    else
    {
    MySettings.Default.Reload();
    }

  5. Add the following line in the DefaultButtonClick event in the Dialog Form:

    MySettings.Default.Reset();

Note: Save(), Reload(), Reset() are common .Net functions of the ApplicationSettingsBase class. The detailed explanation on this can be seen at http://www.codeproject.com/KB/dotnet/user_settings.aspx (thanks BillW for the link).

This code works perfectly, save and restore the user setting without problem, but "reset to default" functionality differs from what I see in many popular software. In my implementation "Reset" cannot be canceled (because Settings.Default.Reset() cannot be reverted back), however if you see an option dialog of some popular program (for example, "Folder options" in the Windows Explorer), reset can be canceled by pressing Cancel button.

So, what is the best and simple way to implement the "traditional" way of the "Reset" functionality?

Update (and probably the best answer)

Currently I have resolved the problem the following way. Instead of

MySettings.Default.Reset();

that cannot be reverted back, I read of the default values directly like this:

MySettings.Default.MyBoolValue = bool.Parse((string)MySettings.Default.Properties["MyBoolValue "].DefaultValue);

Now all works just the way I wanted, but actually I feel this code to be a little bit dirty, because I need to do this for each variable individually, perform type converting, and so on. If somebody knows the better simple solution, please post here.

+2  A: 

What you are doing will "work" but its not very flexible.

In practice I have found copying the settings values to a POCO (plain old clr object) to work best, on "reset" you throw the object away, on save, copy the values back and Save().

When you do the binding etc you would bind to the copy of the settings. if you have multiple "sets" of settings this helps keep things organised to.

Make sense? Your plan is good though ;-)

Paul Kohler
This is probably the best way to do anything like that. Map the work to be done into a value/struct/command object/whatever, and if you cancel, just throw the thing away.
kyoryu
@BillW: He didn't say anything about databases. A DTO is a Data Transfer Object - basically, a dumb struct without identity. Making your changes to one, and then either saving it when done, or discarding it, is a very goo dway to do what you want.
kyoryu
@Kyoru imho this answer not "on target" : in .NET "DTO" has a specific meaning : http://msdn.microsoft.com/en-us/library/ms978717.aspx : the broader definition of DTO as "design pattern" is related to databases, Java ! This answer does not respond to the issue of the OP's code (Reset function) not working properly : we assume the OP is asking for help with that. fyi : the original question did not disclose important implementation details, also, which you can read in OP's comment to my answer. So we're all using "psychic powers" here, it seems. Or, depending on your perspective, wasting time.
BillW
I suppose I was misunderstood. Save(), Reload(), Reset() are not my functions. They are common .Net functions of the ApplicationSettingsBase class. I updated the original question to be more clear.
Zenya
But the core issue is rolling back the changes to a settings object right? I have no issues using "dto" for non-databased reasons. It is after all a plain old class? Dto's are also used in mvc/presenter/mvvm presentation patterns (and more...)
Paul Kohler
@Paul MVC/MVVM is related to ASP.NET and WPF : this is a WinForms question. If you do recognize the "core issue" : How about posting a link to one article on the NET with sample code where "DTO" is used for persistence and re-setting of settings in a WinForm project that does not involve Database access, n-Tier computing, etc. I'd be happy (I'm not being sarcastic here) to learn more from you.
BillW
@BillW - mvc/presenter/mvvm are all as applicable to a winforms app as to wpf, silverlight or asp.net. They are all variations of the same theme, separation of concerns in presentation patterns. As far as a specific article is concerned its something I have seen many times through work or in open source apps, I don’t particularly remember ever reading an article on it. If it makes things more clear perhaps I should refer to the dto as a POCO (plain old clr object)? The general idea was to use something simple.
Paul Kohler
A: 

As @Paul Kohler mentioned, you could use DTOs. If you go that route, you may want to take a look at AutoMapper. I haven't used it myself, but it looks ideal for your situation.

Another option is to pick up a copy of Rocky Lhotka's Expert C# 2008 Business Objects and implement N-level undo. A coworker recently implemented that at work (based on the 2005 edition) and it's slick.

TrueWill
Yes - automapper is pretty nice :-)
Paul Kohler
@TrueWill If I told you my house had a problem with mosquitoes, would you recommend using cruise missiles :) ?
BillW
@BillW: It's a question of scaling. Look at your solution. If you're doing one dialog form with three settings in one project, that may be feasible. We've got many projects, some with dozens of dialogs and hundreds of settings. How much time do you want to spend writing boilerplate code?
TrueWill
@TrueWill I try and respond to the original question as asked; in this case very significant information as to what that question really is : has only emerged gradually ... which is no big deal : we all have to learn how to use StackOverFlow, and often, imho, it does take a back-and-forth process to refine the question (or our answers to the question).
BillW