Is there a way to save types not listed in Settings.Default?

9

In a Windows Forms application I can create configuration properties.

HoweverthereisnotypeList<T>orDictionary<TKey,TValue>.Clicking"Browse" and searching mscorelib > System.Collections.Generics I see only the type KeyNotFoundException .

Is there any way to extend this setting to support other types? How do I do this?

    
asked by anonymous 01.01.2014 / 18:05

2 answers

6

You can create configurations using your own types (created by you).

For this you should:

1) Define through the System.Configuration.SettingsSerializeAs attribute how your class will be serialized in the configuration file;

2) If you chose in the previous step to serialize in String format, you could implement a TypeConverter for your class. The TypeConverter will be in charge of making the "From / To" of its class to type String , in this case;

A complete example of this all together:

using System.Configuration;
using System.ComponentModel;
using System.Collections.Generic;
using System.Globalization;

public class Parametro
{
    public string Nome { get; set; }
    public string Valor { get; set; }

    public override string ToString()
    {
        return string.Format("{0}={1}", this.Nome, this.Valor);
    }
}

[SettingsSerializeAs(SettingsSerializeAs.String)]
[TypeConverter(typeof(ListaParametrosConverter))]
public class ListaParametros : List<Parametro>
{    
}

public class ListaParametrosConverter : TypeConverter
{

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;

        return base.CanConvertFrom(context, sourceType);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if (destinationType == typeof(string))
            return true;

        return base.CanConvertTo(context, destinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        if (destinationType == typeof(string)) {
            object listaParametros = (ListaParametros)value;

            foreach ( parametro in listaParametros) {
                if (!string.IsNullOrWhiteSpace(sb.ToString)) {
                    sb.Append(",");
                }
                sb.AppendFormat("{0}={1}", parametro.Nome, parametro.Valor);
            }

            return sb.ToString;
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {

        if (value is string) {
            ListaParametros listaParametrosRetorno = new ListaParametros();

            string strValue = (string)value;

            object paresNomesValores = strValue.Split(",");

            foreach ( parNomeValor in paresNomesValores) {
                object parametroDividido = parNomeValor.Split("=");
                string nomeParametro = parametroDividido(0);
                string valorParametro = parametroDividido(1);

                listaParametrosRetorno.Add(new Parametro {
                    Nome = nomeParametro,
                    Valor = valorParametro
                });
            }

            return listaParametrosRetorno;
        }

        return base.ConvertFrom(context, culture, value);
    }

}

For this example, these settings ...

...willresultinthis:

(!) Detail: Your configuration class should be in a separate assembly. For some reason Visual Studio does not recognize the types of settings defined in the project itself.

    
02.01.2014 / 13:12
0

If TKEY and TVALUE are string use the following code:

Example: Dictionary configurationBase;

void SalvarConfiguracao(Dictionary configuracaoBase, string arquivo){
   BinaryWriter w = new BinaryWriter(File.Open(arquivo, FileMode.Create));
  Dictionary.Enumerator enum1 = configuracaoBase.GetEnumerator();
  while(enum1.MoveNext()){
     w.Write(enum1.Current.Key);
     w.Write(enum1.Current.Value);
  }
w.Close();
}

Well I hope I have helped you.

Remembering the Dictionary can be used with class types or structures that have a return. So I advise you to create your own structure and use it in a Dictionary .

    
27.06.2014 / 21:58