我有一个与这篇文章中描述的问题类似的问题: 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 'System.Reflection.RuntimeMethodInfo' to type 'System.Reflection.ConstructorInfo'.
 at Microsoft.VisualStudio.Composition.Reflection.ResolverExtensions.Resolve(ConstructorRef constructorRef)
 at Microsoft.VisualStudio.Composition.RuntimeComposition.RuntimePart.get_ImportingConstructor()
 at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.CreateValue()
 at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.Create()
 at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)
 at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveToState(PartLifecycleState requiredState)
 at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()
 at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.<>c__DisplayClass15_0.<GetExportedValueHelper>b__0()
 at Microsoft.VisualStudio.Composition.DelegateServices.<>c__DisplayClass2_0`1.<As>b__0()
 at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Lazy`1.get_Value()
 at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.GatherTaggers(ITextBuffer textBuffer)</description>
</entry>
这让我相信问题仍然在于缓存,但我不知道如何让这些字体/颜色在主题更改时动态更新。