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.String为System.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(值也可以)访问和编辑,也可以在代码中访问和编辑.
Mik*_*ier 40
储藏:
string value = String.Join(",", intArray.Select(i => i.ToString()).ToArray());
重新创建:
int[] arr = value.Split(',').Select(s => Int32.Parse(s)).ToArray();
编辑:阿贝尔的建议!
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类即可.
这又是更多的代码; 但是,它可以应用于比简单数组更复杂的数据类型.