【问题标题】:DialogPage - string array not persistedDialogPage - 字符串数组未持久化
【发布时间】:2014-06-18 17:00:25
【问题描述】:

我正在为 Visual Studio 开发一个扩展。

我有一个选项页面:

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

Bar 属性可以完美运行并保持不变。

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

引用MSDN:

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

据我了解,我正在使用来自 System.ComponentModel 命名空间的有效组件。

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

【问题讨论】:

  • 你试过 List 而不是 string[] 吗?
  • 当您使用List<string> 时,您必须提供一个具有空构造函数的类,而string 没有。但我什至尝试使用List<MyCustomClass>,其中MyCustomClassstring 的包装类-但这些值不会持续存在。
  • 你试过StringCollection吗?
  • @qqbenq 我试过StringCollection,但它没有被持久化:(

标签: c# visual-studio visual-studio-2012 vsix visual-studio-sdk


【解决方案1】:

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

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

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

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

快速的互联网搜索应该会找到一些示例,让您找到正确的方向。

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

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

【讨论】:

  • 谢谢。我写了自己的转换器,它可以工作(见我的回答)。
【解决方案2】:

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

这里以我的自定义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);
    }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2021-10-30
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多