覆盖自定义 Visual Studio 编辑器中的字体

Posted

技术标签:

【中文标题】覆盖自定义 Visual Studio 编辑器中的字体【英文标题】:Overriding font in custom Visual Studio editor 【发布时间】:2015-01-29 07:11:28 【问题描述】:

问题在于使 VS 扩展中的自定义编辑器看起来与当前主题所指示的不同。编辑器托管在对话框中,并且应该具有托管对话框定义的相同字体。

编辑器的内容类型定义如下:

[Export]
[Name("MyContent")]
[BaseDefinition("code")]
public static readonly ContentTypeDefinition ExportContentTypeDefinition = null;

还有一个分类类型定义:

[Export]
[Name("MyContentText")]
[BaseDefinition("text")]
public static readonly ClassificationTypeDefinition MyTextDefinition = null;

分类器提供者定义如下:

[Export(typeof(IClassifierProvider))]
[ContentType("MyContent")]
public class ClassifierProvider : IClassifierProvider

    [Import]
    public IClassificationTypeRegistryService ClassificationTypesRegistry  get; set; 

    public IClassifier GetClassifier(ITextBuffer textBuffer)
    
        return new Classifier(
            ClassificationTypesRegistry.GetClassificationType("MyContentText"));
    

虽然分类器只是为任何快照提供相同的格式:

public class Classifier : IClassifier

    private readonly IClassificationType _classificationType;

    public Classifier(IClassificationType classificationType)
    
        _classificationType = classificationType;
    

    public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
    
        return new []  new ClassificationSpan(span, _classificationType);
    

    public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;

现在,在代码中,在创建编辑器时,我试图覆盖匹配的 IClassificationFormatMap 的属性:

var contentType = contentTypeRegistryService.GetContentType("MyContent");
var textBuffer = textBufferFactoryService.CreateTextBuffer(initialText, contentType);
var textView = textEditorFactoryService.CreateTextView(textBuffer);

...

var formatMap = classificationFomatMapService
    .GetClassificationFormatMap("MyContentText");

formatMap.DefaultTextProperties = formatMap.DefaultTextProperties
    .SetFontRenderingEmSize(dialog.FontSize)
    .SetTypeface(
        new Typeface(
            dialog.FontFamily,
            dialog.FontStyle,
            dialog.FontWeight,
            dialog.FontStretch));

但是,更改不会影响我的编辑器实例。

此外,classificationFomatMapService.GetClassificationFormatMap(ITextView) 重载返回的格式映射与我上面使用的重载返回的格式映射不同。并且更改另一种格式实例也会影响正在运行的 Visual Studio 实例中的所有代码编辑器,因此我必须得出结论,尽管我做出了努力,但 textView 还是会以某种方式映射到默认编辑器的分类。

我的问题是:我应该怎么做才能控制为自定义内容类型指定的自定义编辑器的文本外观?

【问题讨论】:

DefaultTextProperties 适用于所有分类类型,因此这似乎是个问题。您是否尝试过SetTextProperties()? msdn.microsoft.com/en-us/library/… 即使它们确实适用于所有类型,在我通过类型名称获得的格式映射上更改它们也没有任何可见的效果。因此,我想设置文本属性也不会产生任何影响。不过我会试试的,谢谢你的建议。 嗯...听起来“MyContentText”分类未应用于您的 TextView。这就是为什么改变它不会有任何明显的效果。 GetClassifier() 在创建缓冲区时是否正在运行?此外,您正在编辑formatMap 创建缓冲区。我相信你需要事先这样做。 GetClassifier 方法被调用,分类器的 GetClassificationSpans 也被调用,带有预期的文本。正如我所说,更改从 GetClassificationFormatMap(ITextView) 重载返回的格式映射的 DefaultTextProperties 甚至会立即影响主 VS 编辑器。所以缓冲区是否已经创建并不重要。 @galenus,我有same issue,但仅用于重量,另一种字体的字段应用得很好。您找到解决此问题的方法了吗? 【参考方案1】:

我认为你走在正确的道路上,但你需要做一些类似于ViewCreationListener of the italicizing comments extension 的事情。具体来说,将 GetClassificationFormatMap 用于视图(使用以您的内容类型为键的视图创建侦听器),而不是设置默认文本属性,而是为您的分类类型设置属性。正如您所观察到的,格式映射确实在视图之间共享,因此您不想更改默认值。

您可能需要为该类型提供 ClassificationFormatDefinition。也许无论如何都想这样做,只是为了在字体和颜色中显示一些东西。


对于后代:我不认为GetClassificationFormatMap(String) 方法采用 ContentType。我手头没有代码,我完全不记得它是如何工作的,但我认为“外观类别”与内容类型无关。

【讨论】:

以上是关于覆盖自定义 Visual Studio 编辑器中的字体的主要内容,如果未能解决你的问题,请参考以下文章

求助visual studio2013怎么设置参考线,以及怎么自定义代码配色

Visual Studio 颜色主题 - 仅应用“文本编辑器”颜色(没有其他自定义 UI 颜色)

如何在 Visual Studio 代码中使用自定义字体

visual studio code教程:基础使用和自定义设置

Visual Studio 2019 修改注释快捷键和添加自定义头部注释

Visual Studio Shell 2015 不在解决方案资源管理器中使用自定义图标