【问题标题】:"Program options" dialog with the "Reset" capability - best practice具有“重置”功能的“程序选项”对话框 - 最佳实践
【发布时间】:2010-02-19 02:04:27
【问题描述】:

在 C# (vs2005) 中使用“重置为默认值”功能实现“程序选项”对话框的最佳方法是什么?

下面是我的做法。

  1. 创建一个对话框并添加一些控件(如复选框)。还要添加三个按钮:确定、取消、默认。
  2. 创建设置文件并在用户范围内添加一些字段。
  3. 通过 Visual Studio 属性对话框中的“应用程序设置”属性将对话框控件与相应的设置字段绑定。
  4. 在所有者表单中添加一些代码:

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

  5. 在对话框窗体的 DefaultButtonClick 事件中添加以下行:

    MySettings.Default.Reset();

注意: Save()、Reload()、Reset() 是 ApplicationSettingsBase 类的常用 .Net 函数。对此的详细解释可见http://www.codeproject.com/KB/dotnet/user_settings.aspx(感谢BillW提供链接)。

这段代码完美运行,保存和恢复用户设置没有问题,但是“重置为默认”功能与我在许多流行软件中看到的不同。在我的实现中,“重置”无法取消(因为 Settings.Default.Reset() 无法恢复),但是如果您看到一些流行程序的选项对话框(例如,Windows 资源管理器中的“文件夹选项”),请重置可以按取消按钮取消。

那么,实现“重置”功能的“传统”方式的最佳且简单的方法是什么?

更新(可能是最佳答案)

目前我已经通过以下方式解决了这个问题。而不是

MySettings.Default.Reset();

无法恢复,我直接读取默认值是这样的:

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

现在一切都按照我想要的方式工作,但实际上我觉得这段代码有点脏,因为我需要为每个变量单独执行此操作,执行类型转换等等。如果有人知道更好的简单解决方案,请在此处发布。

【问题讨论】:

  • VS2005中的Windows应用项目
  • Zenya,欢迎来到 StackOverflow。我是否建议您尝试尽可能具体地回答具体问题,以便在此处获得最佳响应。您的问题可能与 WPF 项目有关,其中“绑定”的含义可能与 WinForms 中的含义截然不同。祝你好运,
  • 谢谢!之前对 WPF 几乎一无所知。当然,这是 WinForms 项目。
  • 啊,知道您正在使用 ApplicationSettingsBase 类在这里有很大的不同,如果我知道这一点,我不会像以前那样回答您的问题。鉴于我们现在所知道的,我基于假设它不是“焦点”而删除了我的答案。这篇关于代码项目的文章,2009 年 3 月更新,可能对您有所帮助: Jani Giannoudis 的“应用用户设置” codeproject.com/KB/dotnet/user_settings.aspx 我们都在这里学习,在 StackOverFlow 上,没有任何问题我们的问题和答案都通过来回“完善”。祝你好运,
  • 感谢您的链接。很高兴看到我对 ApplicationSettings 类的理解是正确的。我也确信使用这个类来保存和恢复用户选项是很常见的,每个人都知道。这就是为什么我没有在问题正文中做太多解释的原因。虽然我的问题不是这是如何工作的,而是人们通常会做什么来重置用户选项。无论如何,现在我对我提出的解决方案感到满意。

标签: c# visual-studio-2005 settings


【解决方案1】:

你正在做的事情会“工作”,但它不是很灵活。

在实践中,我发现将设置值复制到 POCO(普通的旧 clr 对象)效果最好,在“重置”时将对象扔掉,在保存时,将值复制回来并保存()。

当您进行绑定等时,您将绑定到设置的副本。如果您有多个“组”设置,这有助于使事情井井有条。

有意义吗?不过你的计划很好;-)

【讨论】:

  • 这可能是做类似事情的最佳方式。将要完成的工作映射到一个值/结构/命令对象/任何东西,如果你取消,就把它扔掉。
  • @BillW:他没有提到数据库。 DTO 是一个数据传输对象——基本上,一个没有身份的哑结构。对其中一个进行更改,然后在完成后保存或丢弃它,这是做你想做的事的好方法。
  • @Kyoru imho 这个答案不是“目标”:在 .NET 中“DTO”具有特定含义:msdn.microsoft.com/en-us/library/ms978717.aspx:DTO 更广泛的定义为“设计模式”与数据库、Java 有关!这个答案没有回应 OP 的代码(重置功能)无法正常工作的问题:我们假设 OP 正在寻求帮助。仅供参考:原始问题也没有透露重要的实现细节,您可以在 OP 对我的回答的评论中阅读。所以我们似乎都在这里使用“精神力量”。或者,根据您的观点,浪费时间。
  • 我想我被误解了。 Save()、Reload()、Reset() 不是我的函数。它们是 ApplicationSettingsBase 类的常见 .Net 函数。我更新了原始问题以更清楚。
  • 但核心问题是回滚对设置对象的更改,对吧?由于非基于数据的原因,我使用“dto”没有任何问题。这毕竟是一个普通的老班? Dto 也用于 mvc/presenter/mvvm 演示模式(以及更多...)
【解决方案2】:

这是我的实现方式。

[SettingsProvider(typeof(FileSettingsProvider))]
internal sealed partial class Settings: ApplicationSettingsBase {
    private static Settings defaultInstance = (Settings)ApplicationSettingsBase.Synchronized(new Settings())));
    public static Settings Default {
        get {
            return defaultInstance;
        }
    }

    public T GetDefaultValue<T>(string setting) {
        try {
            if (typeof(T) != typeof(string))
                return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString((string)this.Properties[setting].DefaultValue);
            else
                return (T)this.Properties[setting].DefaultValue;
        }
        catch {
            return default(T);
        }
    }

    [UserScopedSetting()]
    [DefaultSettingValue("512")]
    public int Delay {
        get {
            return ((int)(this["Delay"]));
        }
        set {
            this["Delay"] = value;
        }
    }
}

以及这个方法的用法:

int d = Settings.Default.GetDefaultValue<int>("Delay");

我创建类 Settings 是因为我想存储在同一个项目中实现的类型,并有机会将我自己的 SettingsProvider 分配给整个类,而不是分配给每个属性。所以我在我的课程中加入了 GetDefaultValue 方法。但是,如果您使用由设计器生成的类设置,则不会阻止使用方法。只需在其他地方实现它:

public T GetDefaultValue<T>(string setting) {
    try {
        if (typeof(T) != typeof(string))
            return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString((string)Settings.Default.Properties[setting].DefaultValue);
        else
            return (T)Settings.Default.Properties[setting].DefaultValue;
    }
    catch {
        return default(T);
    }
}

【讨论】:

    【解决方案3】:

    正如@Paul Kohler 提到的,您可以使用DTOs。如果你走那条路,你可能想看看AutoMapper。我自己没有使用过,但它看起来很适合您的情况。

    另一种选择是获取 Rocky Lhotka 的 Expert C# 2008 Business Objects 的副本并实施 N 级撤消。一位同事最近在工作中实现了这一点(基于 2005 年版),而且很流畅。

    【讨论】:

    • 是的 - 自动映射器非常好:-)
    • @TrueWill 如果我告诉你我的房子有蚊子问题,你会推荐使用巡航导弹:) 吗?
    • @BillW:这是一个缩放问题。看看你的解决方案。如果您在一个项目中使用三个设置进行一个对话框表单,那可能是可行的。我们有很多项目,有些项目有几十个对话框和数百个设置。您想花多少时间编写样板代码?
    • 我尝试按原问题回答;在这种情况下,关于这个问题到底是什么的非常重要的信息:只是逐渐出现......这没什么大不了的:我们都必须学习如何使用 StackOverFlow,而且通常,恕我直言,它确实需要一个回——完善问题(或我们对问题的答案)的第四个过程。
    猜你喜欢
    • 2016-09-24
    • 2012-09-10
    • 2011-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多