存储和检索设置是许多扩展的必备项。 让我们探讨如何使用以下目标使用设置:
- 提供自定义选项的简单方法。
- 公开“工具>选项”对话框中的选项。
- 访问和修改设置的线程安全方法。
- 同步和异步支持。
- 无需加载包,以便设置进行初始化。
以下视频演示了如何向扩展添加选项。
下面是“工具>选项”对话框中的外观。
“添加选项”页
右键单击项目并选择“ 添加新 > 项...” 以显示可用的模板。 然后选择左侧的 “扩展性 ”类别,然后选择 “选项页”(社区) 模板。 在 下面的名称 字段中,编写 “常规”。
这将在项目的根目录中创建 /Options/General.cs 。
以下是 General.cs 文件的内容:
internal partial class OptionsProvider
{
// Register the options with these attributes on your package class:
// [ProvideOptionPage(typeof(OptionsProvider.GeneralOptions), "MyExtension", "General", 0, 0, true)]
// [ProvideProfile(typeof(OptionsProvider.GeneralOptions), "MyExtension", "General", 0, 0, true)]
public class GeneralOptions : BaseOptionPage<General> { }
}
public class General : BaseOptionModel<General>
{
[Category("My category")]
[DisplayName("My Option")]
[Description("An informative description.")]
[DefaultValue(true)]
public bool MyOption { get; set; } = true;
}
这是简短和简单的,我们将介绍细节。 但首先,我们必须注册“选项”页。
注册“选项”页
在 General.cs 文件中的代码注释中,说明如何注册“选项”页。
我们只需将这两个属性复制到 Package 类中。 这看起来可能如下所示:
[ProvideOptionPage(typeof(OptionsProvider.GeneralOptions), "MyExtension", "General", 0, 0, true)]
[ProvideProfile(typeof(OptionsProvider.GeneralOptions), "MyExtension", "General", 0, 0, true)]
public sealed class OptionsPackage : ToolkitPackage
{
...
}
运行扩展后,现在应会看到“工具>选项”对话框中显示的“MyExtension/常规选项”页。
这两个属性非常相似,但处理不同的方案。
该 ProvideOptionsPage
属性使“选项”页显示在 “工具 > 选项 ”对话框中。 如果不希望用户看到选项页,可以省略此属性。
ProvideProfile
在漫游配置文件上注册选项,这意味着各个设置将在实例和 Visual Studio 安装之间与用户帐户一起漫游。 它还启用 Visual Studio 的导入/导出设置功能。 此属性是可选的。
各个选项
在 General.cs 文件中,可以看到各个选项的修饰方式不仅仅是用属性修饰的简单 C# 属性。
[Category("My category")]
[DisplayName("My Option")]
[Description("An informative description.")]
[DefaultValue(true)]
public bool MyOption { get; set; } = true;
简单数据类型(例如 string
, bool
) int
都现成支持,涵盖大多数用例。 对于其他数据类型,必须使用类型转换器。 有些内置于 Visual Studio 中,例如 EnumConverter
.
请考虑以下枚举:
public enum Numbers
{
First,
Second,
Third,
}
可以通过声明 TypeConverter
如下所示,将这些值公开为下拉列表中的选项:
[Category("My category")]
[DisplayName("My Enum")]
[Description("Select the value you want from the list.")]
[DefaultValue(Numbers.First)]
[TypeConverter(typeof(EnumConverter))]
public Numbers MyEnum { get; set; } = Numbers.First;
读取和写入选项
现在,你已经注册了允许用户更改其值的选项,接下来可以读取这些值以在我们的扩展中使用。
可以使用同步上下文和异步上下文中的设置。 让我们从同步开始:
// read settings
var number = General.Instance.MyEnum;
// write settings
General.Instance.MyEnum = Numbers.Second;
General.Instance.Save();
用于读取和写入设置的 API 非常简单和直接。
在异步上下文中工作时,API 看起来非常相似。
// read settings
var general = await General.GetLiveInstanceAsync();
var number = general.MyEnum;
// write settings
general.MyEnum = Numbers.Second;
await general.SaveAsync();
事件
保存设置后,将触发静态事件 General.Saved
。 可以像 .NET 中的任何其他事件一样订阅该事件,如下所示:
General.Saved += OnSettingsSaved;
...
private void OnSettingsSaved(object sender, General e)
{
}
获取源代码
可以在示例存储库中找到此扩展的源代码。
相关内容
阅读有关这些方案的所有详细信息的文档,但请注意,虽然它们确实提供了更详细的文档,但它们不会遵循此示例中概述的最佳做法。 它们也不使用社区工具包,使使用设置变得容易得多。