我想要实现的非常简单:我有一个Windows窗体(。NET 3.5)应用程序使用路径来读取信息。用户可以使用我提供的选项表单修改此路径。

现在,我想将路径值保存到一个文件中以供以后使用。这将是保存到该文件中的众多设置之一。该文件将直接位于应用程序文件夹中。

我知道有三种选择:

配置文件(appname.exe.config) 注册表 自定义XML文件

我读到。net配置文件不能将值保存回配置文件。至于注册表,我想尽量远离它。

这是否意味着我应该使用自定义XML文件来保存配置设置?

如果是这样,我想看看代码的例子(c#)。

我看过其他关于这个问题的讨论,但我仍然不清楚。


当前回答

我不喜欢使用网络的解决方案。Config或app.config。尝试读取您自己的XML。看一下XML设置文件-没有更多的web.config。

其他回答

有时你想要去掉传统网络中保留的那些设置。Config或app.config文件。您希望对设置项的部署和分离的数据设计进行更细粒度的控制。或者需求是支持在运行时添加新条目。

我可以想到两个好的选择:

强类型版本和 面向对象版本。

强类型版本的优点是强类型设置名称和值。没有混合名称或数据类型的风险。缺点是更多的设置必须被编码,不能在运行时添加。

使用面向对象版本的优点是可以在运行时添加新的设置。但是您没有强类型的名称和值。必须小心使用字符串标识符。获取值时必须知道之前保存的数据类型。

您可以在这里找到这两个全功能实现的代码。

我想分享我为此建立的一个库。这是一个很小的库,但比.settings文件有很大的改进(恕我冒昧)。

这个库被称为Jot (GitHub)。这是我写的一篇关于它的旧的代码项目文章。

下面是如何使用它来跟踪窗口的大小和位置:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}

与.settings文件相比的好处是:代码相当少,而且容易出错的情况也少得多,因为每个属性只需要提到一次。

对于设置文件,您需要提到每个属性五次:一次是在显式创建属性时,另外四次是在来回复制值的代码中。

存储、序列化等是完全可配置的。当目标对象由IoC容器创建时,您可以[连接它][],以便它自动应用跟踪到它所解析的所有对象,因此要使属性持久,您所需要做的就是在其上添加[Trackable]属性。

它是高度可配置的,你可以配置: -当数据被持久化并应用于全局或每个跟踪对象时 -它是如何序列化的 -存储在哪里(例如文件,数据库,在线,隔离存储,注册表) -可以取消为属性应用/持久化数据的规则

相信我,图书馆是一流的!

public static class SettingsExtensions
{
    public static bool TryGetValue<T>(this Settings settings, string key, out T value)
    {
        if (settings.Properties[key] != null)
        {
            value = (T) settings[key];
            return true;
        }

        value = default(T);
        return false;
    }

    public static bool ContainsKey(this Settings settings, string key)
    {
        return settings.Properties[key] != null;
    }

    public static void SetValue<T>(this Settings settings, string key, T value)
    {
        if (settings.Properties[key] == null)
        {
            var p = new SettingsProperty(key)
            {
                PropertyType = typeof(T),
                Provider = settings.Providers["LocalFileSettingsProvider"],
                SerializeAs = SettingsSerializeAs.Xml
            };
            p.Attributes.Add(typeof(UserScopedSettingAttribute), new UserScopedSettingAttribute());
            var v = new SettingsPropertyValue(p);
            settings.Properties.Add(p);
            settings.Reload();
        }
        settings[key] = value;
        settings.Save();
    }
}

registry/configurationSettings/XML参数似乎仍然非常活跃。随着技术的进步,我都用过了,但我最喜欢的是基于Threed的系统和隔离存储的结合。

下面的示例允许将名为properties的对象存储到隔离存储中的文件中。如:

AppSettings.Save(myobject, "Prop1,Prop2", "myFile.jsn");

可以使用以下方法恢复属性:

AppSettings.Load(myobject, "myFile.jsn");

这只是一个示例,并不是最佳实践的建议。

internal static class AppSettings
{
    internal static void Save(object src, string targ, string fileName)
    {
        Dictionary<string, object> items = new Dictionary<string, object>();
        Type type = src.GetType();

        string[] paramList = targ.Split(new char[] { ',' });
        foreach (string paramName in paramList)
            items.Add(paramName, type.GetProperty(paramName.Trim()).GetValue(src, null));

        try
        {
            // GetUserStoreForApplication doesn't work - can't identify.
            // application unless published by ClickOnce or Silverlight
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Create, storage))
            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write((new JavaScriptSerializer()).Serialize(items));
            }

        }
        catch (Exception) { }   // If fails - just don't use preferences
    }

    internal static void Load(object tar, string fileName)
    {
        Dictionary<string, object> items = new Dictionary<string, object>();
        Type type = tar.GetType();

        try
        {
            // GetUserStoreForApplication doesn't work - can't identify
            // application unless published by ClickOnce or Silverlight
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Open, storage))
            using (StreamReader reader = new StreamReader(stream))
            {
                items = (new JavaScriptSerializer()).Deserialize<Dictionary<string, object>>(reader.ReadToEnd());
            }
        }
        catch (Exception) { return; }   // If fails - just don't use preferences.

        foreach (KeyValuePair<string, object> obj in items)
        {
            try
            {
                tar.GetType().GetProperty(obj.Key).SetValue(tar, obj.Value, null);
            }
            catch (Exception) { }
        }
    }
}

我不喜欢使用网络的解决方案。Config或app.config。尝试读取您自己的XML。看一下XML设置文件-没有更多的web.config。