Вот что я мог бы получить, я думаю, это очень похоже на то, что вам нужно.Я собираюсь обновить это с более подробной информацией, если у вас есть вопросы.
Я начал с этого образца с веб-сайта VS 2010 SDK.Это уже довольно близко к тому, что вам нужно, но требует еще нескольких шагов.
Скачать версию C #, распаковать в папку, скомпилировать.Чтобы запустить его и протестировать, вам нужно перейти в Project> Properties> Debug
. Вам нужно выбрать опцию «Start External Program» и указать путь к вашему приложению VS 2010, например, C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe
* 1015.* В аргументах командной строки задайте:
/rootsuffix Exp
Теперь вы сможете запустить его, создать какой-нибудь пример проекта в открытом VS и, если вы наберете где-нибудь шестизначное число, например 00AA00
itбудет отображаться в виде прямоугольника с соответствующим цветом.Закройте экземпляр отладочной 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 };
}
. Вы можете изменить путь к изображению, который вам нужен.Я только что загрузил логотип SO из Википедии и поместил в свою временную папку.
Скомпилируйте и запустите.Вы должны иметь возможность видеть логотип SO рядом с комментариями в экземпляре отладочной VS.
Некоторые дополнительные замечания.
Во-первых, таким образом выпросто получите рабочий прототип, чтобы начать, вы должны переименовать классы и очистить код для ваших нужд.
Во-вторых, когда я отлаживал его, моя отладочная 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));
}