如何在应用程序设置中存储int []数组

sid*_*guy 90 c# arrays settings winforms

我正在使用C#express 2008创建一个简单的Windows窗体应用程序.我是一位经验丰富的C++开发人员,但我对C#和.NET几乎全新.

我目前正在使用设置设计器和代码存储我的一些简单应用程序设置,如下所示:

// Store setting  
Properties.Settings.Default.TargetLocation = txtLocation.Text;  
...  
// Restore setting  
txtLocation.Text = Properties.Settings.Default.TargetLocation;  
Run Code Online (Sandbox Code Playgroud)

现在我想存储一个ints(int[])数组,或者可能存储一个ints()列表List< int >作为设置.但是,我无法弄清楚如何做到这一点.我搜索了文档,stackoverflow和谷歌,我找不到如何做到这一点的体面解释.

基于我发现的稀疏示例,我的预感是我必须创建一个可序列化的类来包装我的数组或List,然后我将能够在设置设计器中使用该类型.但是,我不确定如何做到这一点.

Jen*_*Ari 132

还有另一个解决方案 - 需要对设置文件进行一些手动编辑,但之后在VS环境和代码中工作正常.并且不需要额外的功能或包装.

问题是,VS允许int[]在设置文件中默认序列化类型 - 它默认情况下不允许您选择它.因此,创建一个具有所需名称的设置(例如SomeTestSetting)并使其成为任何类型(例如string默认情况下).保存更改.

现在转到项目文件夹并使用文本编辑器打开"Properties\Settings.settings"文件(例如,记事本)或者您可以通过右键单击解决方案资源管理器中的" - >属性 - > Settings.settings"在VS中打开它",选择"打开方式...",然后选择"XML编辑器"或"源代码(文本)编辑器".在打开的xml设置中找到您的设置(它将如下所示):

<Setting Name="SomeTestSetting" Type="System.String" Scope="User">
  <Value Profile="(Default)" />
</Setting>
Run Code Online (Sandbox Code Playgroud)

将"类型"参数更改System.StringSystem.Int32[].现在这部分将如下所示:

<Setting Name="SomeTestSetting" Type="System.Int32[]" Scope="User">
  <Value Profile="(Default)" />
</Setting>
Run Code Online (Sandbox Code Playgroud)

现在保存更改并重新打开项目设置 - 瞧!- 我们设置了SomeTestSetting类型System.Int32[],可以通过VS Settings Designer(值也可以)访问和编辑,也可以在代码中访问和编辑.

  • +1 ..不明白为什么这不被接受答案..不需要额外的代码(只修改现有的xml的一行),你得到类型安全和完整vs设计师支持! (9认同)
  • 对于任何好奇的人来说,`int []`的配置文件XML语法看起来像这样(除了漂亮打印):`<setting name ="SomeTestSetting"serializeAs ="String"> <value> <ArrayOfInt xmlns:xsi ="http ://www.w3.org/2001/XMLSchema-instance"xmlns:xsd ="http://www.w3.org/2001/XMLSchema"> <int> 1 </ int> <int> 2 </ int > <int>的3 </ int>的</ ArrayOfInt> </值> </设定>` (6认同)
  • 真棒.要在Visual Studio中使用编辑器输入某些东西,你应该粘贴这样的东西,这是一个字符串数组,这就是我需要的东西<?xml version ="1.0"encoding ="utf-16"?> <ArrayOfString xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd ="http://www.w3.org/2001/XMLSchema"> <string> String1 </ string> < string> String2 </ string> </ ArrayOfString> (5认同)
  • @Prabu,手动编辑设置文件后,您可以返回到“项目属性”中的“设置”选项卡并在那里编辑值(只需单击“值”字段,您将在其末尾看到省略号按钮(...)。单击它,您将能够指定您的值)。 (2认同)

Mik*_*ier 40

储藏:

string value = String.Join(",", intArray.Select(i => i.ToString()).ToArray());

重新创建:

int[] arr = value.Split(',').Select(s => Int32.Parse(s)).ToArray();

编辑:阿贝尔的建议!

  • 注意:您需要在您的usings/imports中添加`System.Linq`才能使上述技巧发挥作用. (2认同)

csh*_*net 11

还有另一种方法可以实现这种结果,使用起来更清洁但需要更多代码.我实现了自定义类型和类型转换器,可以使用以下代码:

List<int> array = Settings.Default.Testing;
array.Add(new Random().Next(10000));
Settings.Default.Testing = array;
Settings.Default.Save();
Run Code Online (Sandbox Code Playgroud)

为此,您需要一个带有类型转换器的类型,允许转换为字符串和从字符串转换.您可以通过使用TypeConverterAttribute修饰类型来完成此操作:

[TypeConverter(typeof(MyNumberArrayConverter))]
public class MyNumberArray ...
Run Code Online (Sandbox Code Playgroud)

然后将此类型转换器实现为TypeConverter的派生:

class MyNumberArrayConverter : TypeConverter
{
    public override bool CanConvertTo(ITypeDescriptorContext ctx, Type type)
    { return (type == typeof(string)); }

    public override bool CanConvertFrom(ITypeDescriptorContext ctx, Type type)
    { return (type == typeof(string)); }

    public override object ConvertTo(ITypeDescriptorContext ctx, CultureInfo ci, object value, Type type)
    {
        MyNumberArray arr = value as MyNumberArray;
        StringBuilder sb = new StringBuilder();
        foreach (int i in arr)
            sb.Append(i).Append(',');
        return sb.ToString(0, Math.Max(0, sb.Length - 1));
    }

    public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)
    {
        List<int> arr = new List<int>();
        if (data != null)
        {
            foreach (string txt in data.ToString().Split(','))
                arr.Add(int.Parse(txt));
        }
        return new MyNumberArray(arr);
    }
}
Run Code Online (Sandbox Code Playgroud)

通过在MyNumberArray类上提供一些便捷方法,我们可以安全地从List中分配,完整的类看起来像:

[TypeConverter(typeof(MyNumberArrayConverter))]
public class MyNumberArray : IEnumerable<int>
{
    List<int> _values;

    public MyNumberArray() { _values = new List<int>(); }
    public MyNumberArray(IEnumerable<int> values) { _values = new List<int>(values); }

    public static implicit operator List<int>(MyNumberArray arr)
    { return new List<int>(arr._values); }
    public static implicit operator MyNumberArray(List<int> values)
    { return new MyNumberArray(values); }

    public IEnumerator<int> GetEnumerator()
    { return _values.GetEnumerator(); }
    IEnumerator IEnumerable.GetEnumerator()
    { return ((IEnumerable)_values).GetEnumerator(); }
}
Run Code Online (Sandbox Code Playgroud)

最后,要在设置中使用它,请将上述类添加到程序集并进行编译.在Settings.settings编辑器中,只需单击"浏览"选项并选择MyNumberArray类即可.

这又是更多的代码; 但是,它可以应用于比简单数组更复杂的数据类型.