Visual Studio 2010 SDK -- 如何在 XML 注释组旁边放置装饰?

发布于 2025-01-05 18:42:36 字数 394 浏览 2 评论 0原文

我无法找到如何执行此操作,并且 Visual Studio SDK 参考也不是很有帮助。

我试图弄清楚如何获取 XML 注释的 NormalizedSnapshotSpanCollection 。我想在它们旁边放置一个图标...我不想在每行旁边放置一个图标,而只想在每组的第一行旁边放置一个图标...

///<summary>SomeXML Comment</summary>   [ICON]
///<remarks>some remarks</remarks>
public void Foo()
{
    ///Some false XML comment line that does not get an icon.
}

I'm having trouble finding out how to do this and the Visual Studio SDK Reference is not very helpful either.

I'm trying to figure out how to get a NormalizedSnapshotSpanCollection of XML comments. I want to place an icon next to them... I don't want an icon next to each line, but only next to the first line of each group...

///<summary>SomeXML Comment</summary>   [ICON]
///<remarks>some remarks</remarks>
public void Foo()
{
    ///Some false XML comment line that does not get an icon.
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苦笑流年记忆 2025-01-12 18:42:36

这是我能得到的,我认为它与你需要的非常相似。如果您有疑问,我将用更多详细信息更新此内容。

VS 2010 图标装饰

我从 此示例来自 VS 2010 SDK 网站。它已经非常接近您的需要,但还需要几个步骤。


下载C#版本,解压到文件夹,编译。要运行它并测试,您需要转到“项目”>“属性>调试

您需要选择“启动外部程序”选项并设置 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 };
    }

您可以将图像路径更改为您需要的图像路径。我刚刚从维基百科下载了 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));
    }

Here's what I could get, I think it's pretty similar to what you need. I'm going to update this with more details, if you have questions.

VS 2010 icon adornment

I started with this sample from VS 2010 SDK web site. It is already pretty close to what you need, but requires several more steps.


Download the C# version, unpack to a folder, compile. To run it and test you need to go to Project > Properties > Debug

You need to choose "Start External Program" option and set path to your VS 2010 app, for example C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe

In the command line arguments set: /rootsuffix Exp

Now you should be able to run it, create some sample project in the opened VS, and if you type anywhere a six-digit number like 00AA00 it will be shown as a rectangle with the corresponding color. Close the debug VS instance.


Now let's edit some code. In ColorAdornmentTagger.cs comment the define #define HIDING_TEXT. This will show the adornment next to the text, not instead of it.

In the same file you need to find where SnapshotSpan adornmentSpan is initialized and change the line to:

SnapshotSpan adornmentSpan = new SnapshotSpan(colorTagSpans[0].End, 0);

This will place adornment after the text span, not before it.


In the ColorTagger.cs. Change the regex in constructor, so the constructor now looks like

    internal ColorTagger(ITextBuffer buffer)
        : base(
        buffer, 
        new[] { new Regex(@"/// <summary>.*", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase) }
        )
    {
    }

This will set the regex to recognize the method commentary line.

Other methods in this class we won't use, you can comment them or return some random color.


In the 'ColorAdornment.cs'. This is the adornment WPF control itself. First change the base class from Button to ContentControl. Change the constructor of the class to

    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 };
    }

You can change the image path to the image path you need. I just downloaded SO logo from Wikipedia and put into my temp folder.

Compile and run. You should be able to see the SO logo next to the comments in the debug VS instance.


Some extra remarks.

First, in this way you just get a working prototype to start with, you should rename the classes and clean-up the code for your needs.

Second, when I was debugging it my debug VS was freezing from time to time. I think this might be related to locks in the IntraTextAdornmentTagger.cs

If you also see freezing, try to update the following method in this way:

    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));
    }

and the AsyncUpdate in this way:

    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));
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文