1

我有一个与这篇文章中描述的问题类似的问题: How to change a ClassificationFormatDefinition

我尝试在我的应用程序中实现这一点,但是当主题更改时,我的 ClassificationFormatDefinition 类定义的字体/颜色更改不会生效。

更多背景信息:我们的 Visual Studio 2015 隔离 Shell 应用程序支持使用 ClassificationFormatDefinition 类突出显示语法的自定义语言。我们没有将颜色定义设为“UserVisible”,而是对格式值(前景、背景、粗体、斜体)进行了硬编码。

[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = "requiredtag")]
[Name("requiredtag")]
[UserVisible(false)]
[Order(After = Priority.Default, Before = Priority.High)]
internal sealed class RequiredTagFormat : ClassificationFormatDefinition
{
    public RequiredTagFormat()
    {
        this.DisplayName = "requiredtag";
        this.ForegroundColor = Colors.Green;
    }
}

为了支持 Light、Blue 和 Dark 主题,我创建了一个辅助类,其中包含定义三个主题使用的颜色的字典。

internal enum Themes
{
    Light = 0,
    Blue = 1,
    Dark = 2,
};

internal static class ThemeHelper
{
    private static Dictionary<Themes, ColorScheme> ColorSchemes = new Dictionary<Themes, ColorScheme>();
    internal static Themes ActiveTheme { get; set; } = Themes.Blue;
    internal static ColorScheme ActiveColorScheme
    {
        get
        {
            return ColorSchemes[ActiveTheme];
        }
    }

ClassificationFormatDefinition 类根据当前主题使用此帮助程序类进行初始化。启动应用程序时一切正常 - 当前主题设置被识别并且所有颜色都是正确的。

[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = "requiredtag")]
[Name("requiredtag")]
[UserVisible(false)]
[Order(After = Priority.Default, Before = Priority.High)]
internal sealed class RequiredTagFormat : ClassificationFormatDefinition, IChangeableClassificationFormatDefinition
{
    public RequiredTagFormat()
    {
        this.DisplayName = "requiredtag";
        this.ForegroundColor = ThemeHelper.ActiveColorScheme.RequiredTag.Foreground ?? this.ForegroundColor;
        this.BackgroundColor = ThemeHelper.ActiveColorScheme.RequiredTag.Background ?? this.BackgroundColor;
        this.IsItalic = ThemeHelper.ActiveColorScheme.RequiredTag.Italic;
        this.IsBold = ThemeHelper.ActiveColorScheme.RequiredTag.Bold;
    }
}

但是,当用户更改主题时,应用程序中的所有颜色都会更新,但自定义语言的语法高亮显示除外。从上面的帖子中,我认为实现 CacheManager 代码会导致 ClassificationFormatDefinition 类被重新初始化,因此采用新主题的颜色,但是在 VSColorTheme.ThemeChanged 事件处理程序中实现 CacheManager 代码后,它没有检测到影响。

我尝试使用可以调用的方法向 ClassificationFormatDefinition 类添加一个接口,以根据当前主题更新每个类的字体/颜色设置,跟踪主题助手中的类实例,然后为每个类调用该方法我在应用程序中处理 VSColorTheme.ThemeChanged 事件时的类。所有这些代码都运行良好。但是,语法高亮仍然没有改变。

[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = "requiredtag")]
[Name("requiredtag")]
[UserVisible(false)]
[Order(After = Priority.Default, Before = Priority.High)]
internal sealed class RequiredTagFormat : ClassificationFormatDefinition, IChangeableClassificationFormatDefinition
{
    public RequiredTagFormat()
    {
        this.DisplayName = "requiredtag";
        ThemeHelper.FormatDefinitions.Add(this);
        Update();
    }

    public void Update()
    {
        this.ForegroundColor = ThemeHelper.ActiveColorScheme.RequiredTag.Foreground ?? this.ForegroundColor;
        this.BackgroundColor = ThemeHelper.ActiveColorScheme.RequiredTag.Background ?? this.BackgroundColor;
        this.IsItalic = ThemeHelper.ActiveColorScheme.RequiredTag.Italic;
        this.IsBold = ThemeHelper.ActiveColorScheme.RequiredTag.Bold;
    }
}

当我尝试在我的项目包中实现上述链接帖子中的 UpdateFont() 方法时,它不仅没有解决问题,而且语言语法突出显示完全停止工作并生成多个 InvalidCastExceptions(记录在 ActivityLog.xml 文件中)任何时候我打开一个代码窗口!

  <entry>
    <record>423</record>
    <time>2020/06/09 18:55:10.974</time>
    <type>Error</type>
    <source>Editor or Editor Extension</source>
    <description>System.InvalidCastException: Unable to cast object of type &apos;System.Reflection.RuntimeMethodInfo&apos; to type &apos;System.Reflection.ConstructorInfo&apos;.&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.Reflection.ResolverExtensions.Resolve(ConstructorRef constructorRef)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeComposition.RuntimePart.get_ImportingConstructor()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.CreateValue()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.Create()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveToState(PartLifecycleState requiredState)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.&lt;&gt;c__DisplayClass15_0.&lt;GetExportedValueHelper&gt;b__0()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.DelegateServices.&lt;&gt;c__DisplayClass2_0`1.&lt;As&gt;b__0()&#x000D;&#x000A;   at System.Lazy`1.CreateValue()&#x000D;&#x000A;--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()&#x000D;&#x000A;   at System.Lazy`1.get_Value()&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.GatherTaggers(ITextBuffer textBuffer)</description>
  </entry>

这让我相信问题仍然在于缓存,但我不知道如何让这些字体/颜色在主题更改时动态更新。

4

0 回答 0