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

Asked

Viewed 282 times

9

In a Windows Forms application I can create configuration properties.

types

However there is the type List<T> or Dictionary<TKey, TValue>. By clicking on "Browse" and searching on mscorelib > System.Collections.Generics I see only the type KeyNotFoundException.

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

  • 1

    A possible solution would be to serialize the list/dictionary in some format that can be saved as a string. Perhaps in json, or merely separate with commas (depending on your T).

  • How about trying to save to an external file. Specify TKEY and TVALUE that I sample the code. OK!?

2 answers

6

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

For that you must:

1) Set using the attribute System.Configuration.SettingsSerializeAs how your class will be serialized in the settings file;

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

A complete example of all this 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...

Aba Settings Visual Studio

...will result in this:

Resultado durante a execução

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

0

If TKEY and TVALUE go 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 helped you.

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.