Comment stocker int [] array dans les paramètres d'application

je crée une application de formulaires de windows simple en utilisant C# express 2008. Je suis un développeur C++ expérimenté, mais je suis assez nouveau en C# et .NET.

je suis en train de stocker certains de mes paramètres d'application simples en utilisant le concepteur de paramètres et le code comme ceci:

// Store setting  
Properties.Settings.Default.TargetLocation = txtLocation.Text;  
...  
// Restore setting  
txtLocation.Text = Properties.Settings.Default.TargetLocation;  

Maintenant, je voudrais stocker soit un tableau d'entiers ( int[] ), ou éventuellement d'une Liste d'entiers ( List< int > ), en tant que décor. Cependant, je ne peux pas comprendre comment faire cela. J'ai cherché dans la documentation, stackoverflow, et google, et je ne peux pas trouver une explication décente de la façon de faire cela.

mon intuition basée sur les exemples épars que j'ai trouvés est que je dois créer une classe qui est sérialisable qui enveloppe mon tableau ou liste, et puis je serai en mesure d'utiliser ce Type dans le concepteur de cadres. Cependant, je ne suis pas sûr exactement comment le faire.

86
demandé sur Aaron Hall 2009-11-20 00:14:13

8 réponses

il y a aussi une autre solution - nécessite un peu d'édition manuelle du fichier de paramètres, mais fonctionne ensuite très bien dans L'environnement VS et dans le code. Et ne nécessite pas de fonctions ou d'enveloppes supplémentaires.

la chose est, que VS permet de sérialiser int[] type par défaut dans le fichier de paramètres - il ne vous permet tout simplement pas de le sélectionner par défaut. Ainsi, créez un paramètre avec le nom désiré (par exemple SomeTestSetting) et faites-le de n'importe quel type (par exemple string par défaut.) Enregistrez les modifications.

maintenant allez dans votre dossier de projet et ouvrez" propriétés\Settings.paramètres "fichier avec éditeur de texte (Bloc-notes, par exemple) ou vous pouvez l'ouvrir dans VS en cliquant avec le bouton droit de la souris dans L'Explorateur de solutions sur" - > Propriétés - > Paramètres.paramètres", sélectionnez " Ouvrir avec..."puis choisissez " XML Editor"ou" Source Code (Text) Editor". Dans les paramètres xml ouverts, Trouvez votre paramètre (il ressemblera à ceci):

<Setting Name="SomeTestSetting" Type="System.String" Scope="User">
  <Value Profile="(Default)" />
</Setting>

modifier le "Type" param de System.String à System.Int32[] . Maintenant cette section ressemblera à ceci:

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

sauvegardez maintenant les modifications et rouvrez les paramètres du projet - voilà! - Nous avons le paramètre SomeTestSetting avec le type System.Int32[] qui peut être consulté et édité par VS Settings Designer (valeurs too), ainsi que dans le code.

125
répondu Jen-Ari 2010-11-24 14:26:00

à conserver:

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

pour re-créer:

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

Edit: Abel suggestion!

40
répondu Mike Gleason jr Couturier 2009-11-19 21:26:46

il y a une autre façon d'atteindre ce résultat qui est beaucoup plus propre dans l'usage mais nécessite plus de code. Mon implémentation d'un convertisseur de type personnalisé le code suivant est possible:

List<int> array = Settings.Default.Testing;
array.Add(new Random().Next(10000));
Settings.Default.Testing = array;
Settings.Default.Save();

pour ce faire, vous avez besoin d'un type avec un convertisseur de type qui permet la conversion vers et à partir de chaînes. Vous faites ceci en décorant le type avec le TypeConverterAttribute:

[TypeConverter(typeof(MyNumberArrayConverter))]
public class MyNumberArray ...

alors la mise en œuvre de ce type de convertisseur comme un dérivation de 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);
    }
}

en fournissant quelques méthodes pratiques sur la classe MyNumberArray que nous pouvons alors attribuer en toute sécurité à et de la liste, la classe complète ressemblerait à quelque chose comme:

[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(); }
}

enfin, pour utiliser ceci dans les paramètres, vous ajoutez les classes ci-dessus à un assemblage et compilez. Dans vos paramètres.éditeur des paramètres il vous suffit de cliquer sur L'option "Parcourir" et de sélectionner la classe MyNumberArray et vous partez.

encore une fois c'est beaucoup plus de code; cependant, il peut être appliqué à des types beaucoup plus compliqués de données qu'un simple tableau.

11
répondu csharptest.net 2009-11-19 22:56:06

spécifie le réglage en tant que système.Collection.Liste de tableaux et ensuite:

Settings.Default.IntArray = new ArrayList(new int[] { 1, 2 });

int[] array = (int[])Settings.Default.IntArray.ToArray(typeof(int));
3
répondu João Angelo 2009-11-19 21:37:35

Une solution simple consiste à définir la valeur par défaut d'un paramètre à null dans la propriété, mais dans le constructeur de vérifier si la propriété est null et si oui, puis le mettre à sa réelle valeur par défaut. Donc si vous voulez un tableau d'entiers:

public class ApplicationSettings : ApplicationSettingsBase
{
    public ApplicationSettings()
    {
        if( this.SomeIntArray == null )
            this.SomeIntArray = new int[] {1,2,3,4,5,6};
    }

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

il se sent un peu hacky, mais son propre et fonctionne comme désiré puisque les propriétés sont initialisées à leurs derniers (ou par défaut) paramètres avant que le constructeur est appelé.

2
répondu Russell Bearden 2011-03-01 19:29:31

Utilisé System.Object .

exemple:

byte[] arBytes = new byte[] { 10, 20, 30 };
Properties.Settings.Default.KeyObject = arBytes;

extrait:

arBytes = (byte[])Properties.Settings.Default.KeyObject;
1
répondu Slavs 2012-10-28 07:51:17

je pense que vous avez raison sur la sérialisation de vos paramètres. Voir ma réponse à cette question pour un exemple:

Techniques pour partager une configuration entre deux applications?

Vous avez une propriété qui est un tableau, comme ceci:

/// <summary>
/// Gets or sets the height.
/// </summary>
/// <value>The height.</value>
[XmlAttribute]
public int [] Numbers { get; set; }
0
répondu Philip Wallace 2017-05-23 12:02:42

font quelques fonctions qui convertissent un tableau int dans une chaîne, mais entre chaque mettre un caractère comme "" (espace).

donc si le tableau est { 1,34,546,56 } la chaîne serait "1 34 645 56"

0
répondu user1452079 2013-08-14 10:47:39