DialogPage - string array not persisted

匆匆过客 提交于 2019-12-23 08:39:08

问题


I'm developing an extension for visual studio.

There I have an option page:

public class GeneralOptionsPage : DialogPage
{
    [Category("General")]
    [DisplayName("Foos")]
    [Description("Bla Foo Bla")]
    public string[] Foos { get; set; }


    [Category("General")]
    [DisplayName("Bar")]
    [Description("Bar Foo Bar")]
    public string Bar { get; set; }
}

The Bar property works perfectly and is persisted.

The Foos Property does also work (it even gives you a nice popup in the options page where you can enter one string per line), which means I can set it and also use it in my extension but it is not written to the registry/storage. When I close VS and open it again it's always empty.

Quote from MSDN:

The default implementation of DialogPage supports properties that have appropriate converters or that are structures or arrays that can be expanded into properties that have appropriate converters. For a list of converters, see the System.ComponentModel namespace. The Visual Studio Extensibility Samples manages int, string, and System.Drawing.Size properties.

In my understanding I'm using valid components from the System.ComponentModel namespace.

So what am I doing wrong? Do I have to treat arrays somehow differently?


回答1:


You will need to implement and associate a custom TypeConverter for your Foos property.

There is no stock converter that covers this scenario, because when you are converting an array of strings to a string, you have to have some sort of delimiter, so you can reconstitute the array from the string. And that will vary depending upon the individual programmers application. Hence the need for a custom TypeConverter.

So you have to derive a new class from System.ComponentModel.TypeConverter, and then associate it with your Foos property. For example:

    [Category("General")]
    [DisplayName("Foos")]
    [Description("Bla Foo Bla")]
    [TypeConverter(typeof(FoosCoverter))]
    public string[] Foos { get; set; }

A quick internet search should pull up a few examples to get you pointed in the right direction.

The DialogPage.SaveSettingsToStorage loops through a collection of the page's PropertyDescriptors, retrieves each propertie's Converter, invokes CanConvertTo and CanConvertFrom to ensure the property can be converted to/from a string, then calls the converter's ConvertToInvariantString to persist the property to the registry value.

Conversely, the DialogPage.LoadSettingsfromStorage loops through the registry values, finds the PropertyDescriptor matching the property on the DialogPage, retrieves its Coverter, then calls CanCovertFrom to ensure the string can be converted back to that particular property type, and then calls the converter's ConvertFromIvariantString, and then assigns the value back to the property.




回答2:


Ed Dore provied the correct answer (thanks).

As an example here my custom TypeConverter:

class StringArrayConverter : TypeConverter
{
    private const string delimiter = "#@#";

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string[]) || base.CanConvertTo(context, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        string v = value as string;

        return v == null ? base.ConvertFrom(context,culture,value) : v.Split(new[] {delimiter}, StringSplitOptions.RemoveEmptyEntries);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        string[] v = value as string[];
        if (destinationType != typeof(string) || v == null)
        {
            return base.ConvertTo(context, culture, value,destinationType);
        }
        return string.Join(delimiter, v);
    }
}


来源:https://stackoverflow.com/questions/24291249/dialogpage-string-array-not-persisted

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!