VSIX:IErrorTag 工具提示内容未显示
VSIX: IErrorTag tooltip content not displaying
我正在尝试使用 MEF 为 visual studio 编写代码分析扩展。我已经为 IErrorTag
实现了 ITagger
接口以及所需的 ITaggerProvider
。结果,对于我的代码分析发现的问题,我在编辑器 window 中得到了预期的曲线。但是,当用鼠标悬停在波浪线上方时,永远不会显示相应的工具提示内容。
这是一个具有相同问题的简约示例:
using Microsoft.VisualStudio.Text.Adornments;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using System;
using System.Collections.Generic;
namespace CodeAnalyzer
{
struct DummyIssue
{
public int Line; // one based line
public string ToolTip;
public DummyIssue(int line, string toolTip)
{
Line = line;
ToolTip = toolTip;
}
}
internal class DummyCodeCheckTagger : ITagger<IErrorTag>
{
readonly List<DummyIssue> mIssues;
readonly ITextView TextView;
public DummyCodeCheckTagger(ITextView textView)
{
TextView = textView;
mIssues = new List<DummyIssue>
{
new DummyIssue(1, "asldfjoqwet"),
new DummyIssue(7, "ASASDAER")
};
textView.LayoutChanged += Update;
}
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
private void Update(object sender, TextViewLayoutChangedEventArgs args)
{
TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(new SnapshotSpan(args.NewSnapshot, 0, args.NewSnapshot.Length)));
}
IEnumerable<ITagSpan<IErrorTag>> ITagger<IErrorTag>.GetTags(NormalizedSnapshotSpanCollection spans)
{
var issues = mIssues;
foreach (var span in spans)
{
foreach (var issue in issues)
{
int zeroBasedLine = issue.Line - 1;
ITextSnapshotLine snapshotLine = TextView.TextSnapshot.GetLineFromLineNumber(zeroBasedLine);
SnapshotSpan snapshotSpan = snapshotLine.Extent;
if (spans.IntersectsWith(snapshotSpan))
{
yield return new TagSpan<IErrorTag>(snapshotSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, issue.ToolTip));
}
}
}
}
}
}
结果如下所示:
tooltip not displaying
我缺少什么才能显示工具提示?
上面Fater的评论让我又开始思考这个问题。由于我已经尝试了 fater 发布的 document 中的建议但没有成功,我开始考虑问题是否可能出在其他地方。
事实证明,ITagger
实现不是问题,但 ITaggerProvider
实现导致了奇怪的行为。为了那个原因,
我几乎遵循 VSIX ErrorList 实施拼写检查器的示例,其中包含以下代码
/// <summary>
/// Create a tagger that does spell checking on the view/buffer combination.
/// </summary>
public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
{
ITagger<T> tagger = null;
// Only attempt to spell check on the view's edit buffer (and multiple views could have that buffer open simultaneously so
// only create one instance of the spell checker.
if ((buffer == textView.TextBuffer) && (typeof(T) == typeof(IErrorTag)))
{
var spellChecker = buffer.Properties.GetOrCreateSingletonProperty(typeof(SpellChecker), () => new SpellChecker(this, textView, buffer));
// This is a thin wrapper around the SpellChecker that can be disposed of without shutting down the SpellChecker
// (unless it was the last tagger on the spell checker).
tagger = new SpellCheckerTagger(spellChecker) as ITagger<T>;
}
return tagger;
}
重点是,上面的代码只为特定视图创建了一个 ITagger
。在这种情况下,创建的标记器仅用于在编辑器 window 视图中提供波浪线。 Visual Studio 使用不同的标记器实例为波浪线提供工具提示,并使用另一个标记器实例为编辑器中的滚动条着色 window。我原以为这将由一个标记器实例完成。
我正在尝试使用 MEF 为 visual studio 编写代码分析扩展。我已经为 IErrorTag
实现了 ITagger
接口以及所需的 ITaggerProvider
。结果,对于我的代码分析发现的问题,我在编辑器 window 中得到了预期的曲线。但是,当用鼠标悬停在波浪线上方时,永远不会显示相应的工具提示内容。
这是一个具有相同问题的简约示例:
using Microsoft.VisualStudio.Text.Adornments;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using System;
using System.Collections.Generic;
namespace CodeAnalyzer
{
struct DummyIssue
{
public int Line; // one based line
public string ToolTip;
public DummyIssue(int line, string toolTip)
{
Line = line;
ToolTip = toolTip;
}
}
internal class DummyCodeCheckTagger : ITagger<IErrorTag>
{
readonly List<DummyIssue> mIssues;
readonly ITextView TextView;
public DummyCodeCheckTagger(ITextView textView)
{
TextView = textView;
mIssues = new List<DummyIssue>
{
new DummyIssue(1, "asldfjoqwet"),
new DummyIssue(7, "ASASDAER")
};
textView.LayoutChanged += Update;
}
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
private void Update(object sender, TextViewLayoutChangedEventArgs args)
{
TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(new SnapshotSpan(args.NewSnapshot, 0, args.NewSnapshot.Length)));
}
IEnumerable<ITagSpan<IErrorTag>> ITagger<IErrorTag>.GetTags(NormalizedSnapshotSpanCollection spans)
{
var issues = mIssues;
foreach (var span in spans)
{
foreach (var issue in issues)
{
int zeroBasedLine = issue.Line - 1;
ITextSnapshotLine snapshotLine = TextView.TextSnapshot.GetLineFromLineNumber(zeroBasedLine);
SnapshotSpan snapshotSpan = snapshotLine.Extent;
if (spans.IntersectsWith(snapshotSpan))
{
yield return new TagSpan<IErrorTag>(snapshotSpan, new ErrorTag(PredefinedErrorTypeNames.SyntaxError, issue.ToolTip));
}
}
}
}
}
}
结果如下所示: tooltip not displaying
我缺少什么才能显示工具提示?
上面Fater的评论让我又开始思考这个问题。由于我已经尝试了 fater 发布的 document 中的建议但没有成功,我开始考虑问题是否可能出在其他地方。
事实证明,ITagger
实现不是问题,但 ITaggerProvider
实现导致了奇怪的行为。为了那个原因,
我几乎遵循 VSIX ErrorList 实施拼写检查器的示例,其中包含以下代码
/// <summary>
/// Create a tagger that does spell checking on the view/buffer combination.
/// </summary>
public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
{
ITagger<T> tagger = null;
// Only attempt to spell check on the view's edit buffer (and multiple views could have that buffer open simultaneously so
// only create one instance of the spell checker.
if ((buffer == textView.TextBuffer) && (typeof(T) == typeof(IErrorTag)))
{
var spellChecker = buffer.Properties.GetOrCreateSingletonProperty(typeof(SpellChecker), () => new SpellChecker(this, textView, buffer));
// This is a thin wrapper around the SpellChecker that can be disposed of without shutting down the SpellChecker
// (unless it was the last tagger on the spell checker).
tagger = new SpellCheckerTagger(spellChecker) as ITagger<T>;
}
return tagger;
}
重点是,上面的代码只为特定视图创建了一个 ITagger
。在这种情况下,创建的标记器仅用于在编辑器 window 视图中提供波浪线。 Visual Studio 使用不同的标记器实例为波浪线提供工具提示,并使用另一个标记器实例为编辑器中的滚动条着色 window。我原以为这将由一个标记器实例完成。