DialogPage - 字符串数组未保留

Osc*_*rEi 8 c# visual-studio visual-studio-sdk vsix visual-studio-2012

我正在开发视觉工作室的扩展.

我有一个选项页面:

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; }
}
Run Code Online (Sandbox Code Playgroud)

Bar物业完美运作并坚持下去.

Foos属性也可以工作(它甚至在选项页面中为您提供了一个很好的弹出窗口,您可以在每行输入一个字符串),这意味着我可以设置它并在我的扩展中使用它,但它不会写入注册表/存储.当我关闭VS并再次打开它时,它总是空着的.

MSDN引用:

DialogPage的默认实现支持具有适当转换器的属性,或者是可以扩展为具有适当转换器的属性的结构或数组的属性.有关转换器列表,请参阅System.ComponentModel命名空间.Visual Studio Extensibility Samples管理int,string和System.Drawing.Size属性.

据我所知,我正在使用System.ComponentModel命名空间中的有效组件.

那么我做错了什么?我是否必须以不同的方式处理数组?

小智 6

您需要为Foos属性实现并关联自定义TypeConverter.

没有库存转换器可以覆盖这种情况,因为当您将字符串数组转换为字符串时,您必须具有某种分隔符,因此您可以从字符串重构数组.这取决于各个程序员的应用程序.因此需要自定义TypeConverter.

因此,您必须从System.ComponentModel.TypeConverter派生一个新类,然后将其与您的Foos属性相关联.例如:

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

一个快速的互联网搜索应该举几个例子,让你指向正确的方向.

DialogPage.SaveSettingsToStorage循环遍历页面PropertyDescriptors的集合,检索每个属性的Converter,调用CanConvertTo和CanConvertFrom以确保属性可以转换为字符串/从字符串转换,然后调用转换器的ConvertToInvariantString将属性保存到注册表值.

相反,DialogPage.LoadSettingsfromStorage循环遍历注册表值,找到与DialogPage上的属性匹配的PropertyDescriptor,检索其Coverter,然后调用CanCovertFrom以确保该字符串可以转换回该特定属性类型,然后调用转换器的ConvertFromIvariantString,然后将值分配回属性.


Osc*_*rEi 5

埃德多尔提出了正确的答案(谢谢).

以我的习惯为例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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 该解决方案对我不起作用。我遇到了与此线程中描述的完全相同的问题http://stackoverflow.com/questions/32751040/store-array-in-options-using-dialogpage (2认同)