Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DialogPage-字符串数组未持久化_C#_Visual Studio_Visual Studio 2012_Vsix_Visual Studio Sdk - Fatal编程技术网

C# DialogPage-字符串数组未持久化

C# DialogPage-字符串数组未持久化,c#,visual-studio,visual-studio-2012,vsix,visual-studio-sdk,C#,Visual Studio,Visual Studio 2012,Vsix,Visual Studio Sdk,我正在为VisualStudio开发一个扩展 我有一个选项页面: public class GeneralOptionsPage : DialogPage { [Category("General")] [DisplayName("Foos")] [Description("Bla Foo Bla")] public string[] Foos { get; set; } [Category("General")] [DisplayName("

我正在为VisualStudio开发一个扩展

我有一个选项页面:

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; }
}
属性可以完美地工作并保持不变

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

引自:

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

据我所知,我使用的是来自
System.ComponentModel
命名空间的有效组件


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

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

没有涵盖此场景的stock converter,因为当您将字符串数组转换为字符串时,必须使用某种分隔符,以便可以从字符串重新构造数组。这取决于各个程序员的应用程序。因此需要定制类型转换器

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

    [Category("General")]
    [DisplayName("Foos")]
    [Description("Bla Foo Bla")]
    [TypeConverter(typeof(FoosCoverter))]
    public string[] Foos { get; set; }
一个快速的互联网搜索应该能举出几个例子,让你找到正确的方向

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


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

Ed Dore提供了正确答案(谢谢)

例如,我的自定义
类型转换器

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);
    }
}

您是否尝试了列表而不是字符串[]?当您使用
List
时,必须提供一个具有空构造函数的类,而
string
没有空构造函数。但是我甚至尝试使用
List
,其中
MyCustomClass
string
的包装器类-但是这些值仍然不会持久。你尝试过了吗?@qqbenq我尝试了
StringCollection
,但它不会持久化:(谢谢。我编写了自己的转换器,它可以工作(见我的答案)。此解决方案不适用于我。我遇到了与此线程中描述的完全相同的问题