在DialogPage设置更改后,反映用户对颜色的更改

时间:2017-05-15 17:22:56

标签: c# visual-studio roslyn visual-studio-extensions vs-extensibility

我正在构建一个扩展来改变C#和VB中不同编程结构的颜色,我使用Roslyn API。我使用PackageDialogPage为用户提供了更改颜色的选项,这是我的选项页面:

enter image description here

我想要的是在用户更改颜色设置后立即更改颜色,并发生SaveSettingsToStorage事件。发生此事件时,我致电Settings.Save保存设置,同样在我的设置课程中,我有Settings.SettingsUpdated个活动,我可以订阅,但我不知道在此活动中我应该拨打什么电话恰好反映用户对颜色的更改,换句话说,更新颜色,这是DialogPage发生的保存事件:

public override void SaveSettingsToStorage()
    {
        var settings = new PresetColors
        {

            Interface = Interface.ToMediaColor(),
            Class = Class.ToMediaColor(),
            AbstractClass = AbstractClass.ToMediaColor(),
            StaticClass = StaticClass.ToMediaColor(),
            Struct = Struct.ToMediaColor(),
            Enum = Enum.ToMediaColor(),
            EnumConstant = EnumConstant.ToMediaColor(),
            Constructor = Constructor.ToMediaColor(),
            Attribute = Attribute.ToMediaColor(),
            Field = Field.ToMediaColor(),
            Namespace = Namespace.ToMediaColor(),
            Method = Method.ToMediaColor(),
            StaticMethod = StaticMethod.ToMediaColor(),
            ExtensionMethod = ExtensionMethod.ToMediaColor(),
            AutomaticProperty = AutomaticProperty.ToMediaColor(),
            TypeParameter = Parameter.ToMediaColor()
        };
        State.Settings.Save(settings);
    }

我用来更改颜色的是ClassificationFormatDefinition,一个实现ITagger<IClassificationTag>ITaggerProvider的类,例如我的标记器:

internal class ColorCoderTagger : ITagger<IClassificationTag>
{
    private ITextBuffer _buffer;
    private readonly ColorCoderTaggerServices _colorCoderTaggerServices;
    private readonly ClassificationTypeFactory _classificationTypeFactory;
    private readonly Dictionary<string, IClassificationType> classificationTypeDictionary;
    private ProviderCache _cache;

    public event EventHandler<SnapshotSpanEventArgs> TagsChanged;

    public ColorCoderTagger(ITextBuffer buffer, IClassificationTypeRegistryService classificationRegistry)
    {
        this._buffer = buffer;
        _classificationTypeFactory = new ClassificationTypeFactory(classificationRegistry);
        classificationTypeDictionary = _classificationTypeFactory.CreateClassificationTypes();
        _colorCoderTaggerServices = new ColorCoderTaggerServices();
    }

    public IEnumerable<ITagSpan<IClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans)
    {
        if (spans.Count == 0)
        {
            return Enumerable.Empty<ITagSpan<IClassificationTag>>();
        }

        var cacheStatus = _colorCoderTaggerServices.ManageCache(ref _cache, spans, _buffer);

        if (cacheStatus == CacheState.NotResolved)
        {
            return Enumerable.Empty<ITagSpan<IClassificationTag>>();
        }

        return _colorCoderTaggerServices.GetClassificationTags(_cache, spans, classificationTypeDictionary);
    }
}

这是我管理缓存的课程:

public class ProviderCache
{
    public Workspace Workspace { get; private set; }
    public Document Document { get; private set; }
    public SemanticModel SemanticModel { get; private set; }
    public SyntaxNode SyntaxRoot { get; private set; }
    public ITextSnapshot Snapshot { get; private set; }

    public static async Task<ProviderCache> Resolve(ITextBuffer buffer, ITextSnapshot snapshot)
    {
        var workspace = buffer.GetWorkspace();
        var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
        if (document == null)
        {
            return null;
        }

        var semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false);
        var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);
        return new ProviderCache
        {
            Workspace = workspace,
            Document = document,
            SemanticModel = semanticModel,
            SyntaxRoot = syntaxRoot,
            Snapshot = snapshot
        };
    }
}

现在,我必须关闭并打开视觉工作室才能使更改生效。我可以通过visual studio的字体和颜色选项更改颜色设置,但我想通过我自己的ColorCoder选项页面进行更改,我很感激任何帮助。

1 个答案:

答案 0 :(得分:0)

可以使用包含在 IVsFontAndColorStorage 中的 VisualStudio.Shell.Interop 来完成。这是一个小示例代码:

    public void Save(IDictionary<String, ColorableItemInfo[]> classifications)
    {
        Guid category = new Guid(Guids.TextEditorCategory);

        uint flags = (uint)(__FCSTORAGEFLAGS.FCSF_LOADDEFAULTS
                          | __FCSTORAGEFLAGS.FCSF_PROPAGATECHANGES);

        Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread();
        var hr = _colorStorage.Storage.OpenCategory(ref category, flags);
        ErrorHandler.ThrowOnFailure(hr);

        try
        {
            foreach (var classification in classifications)
            {
                hr = _colorStorage.Storage.SetItem(classification.Key, classification.Value);
                ErrorHandler.ThrowOnFailure(hr);
            }
        }
        finally
        {
            _colorStorage.Storage.CloseCategory();
        }
    } 

我已经在 ColorCoder Visual Studio 扩展的代码库中使用了它。如果您需要更多与此相关的代码,这是它的 github repository