这是我能得到的,我认为它与您需要的非常相似。如果您有任何疑问,我将更新此内容并提供更多详细信息。
我从 VS 2010 SDK 网站的这个示例开始。它已经非常接近您的需要,但需要更多步骤。
下载C#版本,解压到文件夹,编译。要运行它并进行测试,您需要转到 Project > Properties > Debug
例如,您需要选择“启动外部程序”选项并设置 VS 2010 应用程序的路径C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe
在命令行参数集中:/rootsuffix Exp
现在你应该可以运行它了,在打开的 VS 中创建一些示例项目,如果你在任何地方键入一个六位数的数字,00AA00
它就会显示为具有相应颜色的矩形。关闭调试 VS 实例。
现在让我们编辑一些代码。在ColorAdornmentTagger.cs
评论中定义#define HIDING_TEXT
。这将在文本旁边显示装饰,而不是代替它。
在同一个文件中,您需要找到SnapshotSpan adornmentSpan
初始化的位置并将行更改为:
SnapshotSpan adornmentSpan = new SnapshotSpan(colorTagSpans[0].End, 0);
这将在文本跨度之后而不是之前放置装饰。
在ColorTagger.cs
. 更改构造函数中的正则表达式,因此构造函数现在看起来像
internal ColorTagger(ITextBuffer buffer)
: base(
buffer,
new[] { new Regex(@"/// <summary>.*", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase) }
)
{
}
这将设置正则表达式以识别方法注释行。
这个类中的其他方法我们不会使用,你可以评论它们或者返回一些随机的颜色。
在“ColorAdornment.cs”中。这是装饰 WPF 控件本身。首先将基类从 更改Button
为ContentControl
。将类的构造函数更改为
internal ColorAdornment(ColorTag colorTag)
{
BitmapImage image = new BitmapImage();
using (FileStream stream = File.OpenRead("c:\\temp\\sologo.png"))
{
image.BeginInit();
image.StreamSource = stream;
image.CacheOption = BitmapCacheOption.OnLoad;
image.EndInit();
}
this.Content = new Image() { Margin = new Thickness(20,0,0,0), Width = 100, Height = 30, Source = image };
}
您可以将图像路径更改为您需要的图像路径。我刚刚从 Wikipedia 下载了 SO 徽标并放入了我的临时文件夹。
编译并运行。您应该能够在调试 VS 实例中的注释旁边看到 SO 徽标。
一些额外的说明。
首先,通过这种方式,您只需获得一个工作原型,您应该重命名类并根据需要清理代码。
其次,当我调试它时,我的调试 VS 不时冻结。我认为这可能与IntraTextAdornmentTagger.cs
如果你也看到冻结,尝试用这种方式更新以下方法:
protected void InvalidateSpans(IList<SnapshotSpan> spans)
{
if (spans.Count == 0)
return;
bool wasEmpty = false;
lock (this.invalidatedSpans)
{
wasEmpty = this.invalidatedSpans.Count == 0;
this.invalidatedSpans.AddRange(spans);
}
if (wasEmpty)
this.view.VisualElement.Dispatcher.BeginInvoke(new Action(AsyncUpdate));
}
和 AsyncUpdate 以这种方式:
private void AsyncUpdate()
{
// Store the snapshot that we're now current with and send an event
// for the text that has changed.
if (this.snapshot != this.view.TextBuffer.CurrentSnapshot)
{
this.snapshot = this.view.TextBuffer.CurrentSnapshot;
Dictionary<SnapshotSpan, TAdornment> translatedAdornmentCache = new Dictionary<SnapshotSpan, TAdornment>();
foreach (var keyValuePair in this.adornmentCache)
translatedAdornmentCache.Add(keyValuePair.Key.TranslateTo(this.snapshot, SpanTrackingMode.EdgeExclusive), keyValuePair.Value);
this.adornmentCache = translatedAdornmentCache;
}
List<SnapshotSpan> spansCopy;
lock (this.invalidatedSpans)
{
spansCopy = this.invalidatedSpans.ToList();
this.invalidatedSpans.Clear();
}
List<SnapshotSpan> translatedSpans = spansCopy.Select(s => s.TranslateTo(this.snapshot, SpanTrackingMode.EdgeInclusive)).ToList();
if (translatedSpans.Count == 0)
return;
var start = translatedSpans.Select(span => span.Start).Min();
var end = translatedSpans.Select(span => span.End).Max();
RaiseTagsChanged(new SnapshotSpan(start, end));
}