Max*_*lov 8 visual-studio-sdk vsix visual-studio-2015
假设我需要在刚刚从模板创建的扩展中存储任何数组.
我刚刚创建了新的VSIX项目,为其添加了VSPackage,然后添加了选项页面grid(DialogPage
).然后我按照类似问题的答案的说明:DialogPage
- 字符串数组没有持久化.
而且,为了演示目的,我们还添加了int[]
数组和plain int
以及自定义类型转换器.
// [standard attributes]
[ProvideOptionPage(typeof(OptionPageGrid),
"My Category", "My Grid Page", 0, 0, true)]
public sealed class FooBarVSPackage : Package
{
// standard code
}
public class OptionPageGrid : DialogPage
{
// [typical attributes]
[TypeConverter(typeof(StringArrayConverter))]
public string[] Foos
{ get; set; }
// [typical attributes]
[TypeConverter(typeof(CustomIntConverter))]
public int Bar
{ get; set; }
// [typical attributes]
[TypeConverter(typeof(IntArrayConverter))]
public int[] Bazes
{ get; set; }
}
class StringArrayConverter : TypeConverter
{
// exact copy of code from similar question/answer mentioned above
}
public class IntArrayConverter : TypeConverter
{
private const string delimiter = "#@#";
// CanConvertFrom, ConvertTo, etc. overridden in similar fashion
}
public class CustomIntConverter : TypeConverter
{
// CanConvertFrom() overridden
// CanConvertTo() overridden
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var v = value as string;
return int.Parse(v.TrimStart('*'));
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
var v = (int)value;
return v.ToString().PadLeft(25, '*');
}
}
Run Code Online (Sandbox Code Playgroud)
但是在我重新打开之后,其中两个价值消失了!只有普通人int
坚持:
还有一件奇怪的事情:如何以及何时TypeConverter
调用方法.CanConvertTo()
是从来没有在整个会议期间调用.CanConvertFrom()
并且ConvertTo()
经常以预期的方式被称为或多或少.并且仅在直接编辑选项的字符串表示时ConvertFrom()
调用,即它根本不参与加载/保存选项!
我不确定,但感觉有点像int
选项存储为int
和string
仅在选项GUI中转入/转换,而数组选项只是默默地尝试执行相同操作.
PS:如果你想亲自直接使用这个例子,这里有一个GitHub repo,其中包含有问题的示例项目:FooBarVSIXProject
在花了几个小时试图修复破坏的"易于使用"机制(要么本身已损坏或其文档)之后,我意识到不应该浪费时间,而应该只下降一个抽象层并完全按照我想要的DialogPage
机制自动执行.
人们预计,DialogPage
应该保存/字符串表示(类型转换器获得)装入从/ 用户设置存储(或类似的东西),其时SaveSettingsToStorage()
和LoadSettingsFromStorage()
被调用.既然它拒绝这样做并且那些方法是virtual
,我们可以自己做到这一点:
public class OptionPageGrid : DialogPage
{
const string collectionName = "FooBarVSIX";
[Category("General")]
[DisplayName("Foos")]
[Description("Bla Foo Bla")]
// note that TypeConverter attribute is removed,
// because it's not relevant anymore
public string[] Foos
{ get; set; }
// Bar and Bazes properties missed out to make this example shorter
public override void SaveSettingsToStorage()
{
base.SaveSettingsToStorage();
var settingsManager = new ShellSettingsManager(ServiceProvider.GlobalProvider);
var userSettingsStore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings);
if (!userSettingsStore.CollectionExists(collectionName))
userSettingsStore.CreateCollection(collectionName);
var converter = new StringArrayConverter();
userSettingsStore.SetString(
collectionName,
nameof(Foos),
converter.ConvertTo(this.Foos, typeof(string)) as string);
// save Bazes in similar way
}
public override void LoadSettingsFromStorage()
{
base.LoadSettingsFromStorage();
var settingsManager = new ShellSettingsManager(ServiceProvider.GlobalProvider);
var userSettingsStore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings);
if (!userSettingsStore.PropertyExists(collectionName, nameof(Foos)))
return;
var converter = new StringArrayConverter();
this.Foos = converter.ConvertFrom(
userSettingsStore.GetString(collectionName, nameof(Foos))) as string[];
// load Bazes in similar way
}
}
Run Code Online (Sandbox Code Playgroud)
当然,现在,如果你这样做,你TypeConverter
实际上不必编写和使用.您可以将序列化逻辑直接嵌入到这些方法或任何地方.
此外,您可以将数据直接序列化为二进制格式,并使用 SetMemoryStream()来保存它.
归档时间: |
|
查看次数: |
514 次 |
最近记录: |