91 votes

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

Je suis la création d'une simple application windows Forms à l'aide de C# express 2008. Je suis expérimenté, développeur C++, mais je suis à peu près nouvelle marque de C# et de .NET.

Je suis en train de ranger certains de mes paramètres d'application simple utilisant les paramètres du concepteur 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 > ), comme un paramètre. Cependant, je ne peux pas comprendre comment le faire. J'ai cherché de la documentation, stackoverflow, et google, et je ne peux pas trouver une bonne explication de comment faire cela.

Mon intuition basée sur les rares exemples que j'ai trouvé c'est que je dois créer une classe sérialisable qui enveloppe mon tableau ou d'une Liste, et puis je vais être en mesure d'utiliser ce Type dans les paramètres de concepteur. Cependant, je ne suis pas sûr exactement comment le faire.

Merci d'avance pour votre aide!

133voto

HellKeeper Points 1033

Il y a aussi une autre solution nécessite un peu de la modification manuelle du fichier de paramètres, mais par la suite, fonctionne très bien dans VS l'environnement et dans le code. Et ne nécessite pas de fonctions supplémentaires ou des wrappers.

Le truc, c'est que VS permet de sérialiser int[] type par défaut dans le fichier de settings - il n'a tout simplement pas vous permettre de sélectionner par défaut. Donc, créer un cadre avec le nom de votre choix (par exemple, SomeTestSetting) et de tout type (par exemple, string par défaut). Enregistrer les modifications.

Maintenant, allez dans votre dossier de projet et d'ouvrir les "Propriétés\Paramètres."paramètres du fichier avec un éditeur de texte (bloc-notes, par exemple), Ou vous pouvez l'ouvrir en VS par un clic droit dans l'Explorateur de solutions sur" -> Propriétés -> Paramètres.les paramètres", sélectionnez "Ouvrir Avec..." et puis choisissez "XML Editor" ou "Code Source (Texte) de l'Éditeur". Dans le ouvert xml des paramètres de trouver votre milieu (il ressemble à ceci):

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

Changer le "Type" de param System.String de System.Int32[]. Maintenant, cette section devrait ressembler à ceci:

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

Maintenant enregistrer les modifications et de ré-ouvrir les paramètres de projet - voilà! - Nous avons le paramètre SomeTestSetting de type System.Int32[] qui peut être consulté et modifié par VS les Paramètres de Designer (des valeurs), ainsi que dans le code.

40voto

ranger:

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

recréer:

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

Edit: suggestion d'Abel!

11voto

csharptest.net Points 16556

Il existe une autre façon de parvenir à ce résultat qui est beaucoup plus propre à l'usage, mais nécessite plus de code. Ma mise en œuvre d'un type personnalisé et le type de convertisseur 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 réaliser cela, vous avez besoin d'un type avec un type de convertisseur qui permet la conversion vers et à partir de chaînes de caractères. Vous faites cela en décorant le type avec la TypeConverterAttribute:

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

Ensuite, la mise en œuvre de ce type de convertisseur comme une 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);
    }
}

Par la fourniture de certaines méthodes pratiques sur le MyNumberArray classe on peut alors attribuer en toute sécurité vers et à partir de la Liste, l'ensemble de la classe 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, de l'utiliser dans les paramètres, vous ajoutez les classes ci-dessus à une assemblée et de les compiler. Dans vos Paramètres.les paramètres de l'éditeur vous suffit de cliquer sur le bouton "Parcourir" et sélectionnez le MyNumberArray classe et vous partez.

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

3voto

João Angelo Points 24422

Spécifiez le paramètre en tant que System.Collections.ArrayList puis:

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

int[] array = (int[])Settings.Default.IntArray.ToArray(typeof(int));
 

2voto

Russell Bearden Points 11

Une solution simple consiste à définir la valeur par défaut d'un paramètre sur NULL dans la propriété, mais dans le constructeur, vérifiez si la propriété est null et, le cas échéant, définissez-la sur sa valeur par défaut. Donc, si vous vouliez un tableau d'ints:

 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 semble un peu hacky, mais sa propreté et fonctionne comme souhaité puisque les propriétés sont initialisées à leurs derniers paramètres (ou valeurs par défaut) avant l'appel du constructeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X