8

Tôi đang gặp khó khăn khi tìm hiểu cách thực hiện việc này và Tham khảo SDK Visual Studio cũng không hữu ích.Visual Studio 2010 SDK - Cách đặt một trang sức bên cạnh các nhóm nhận xét XML?

Tôi đang cố gắng tìm hiểu cách nhận được NormalizedSnapshotSpanCollection nhận xét XML. Tôi muốn đặt một biểu tượng bên cạnh họ ... Tôi không muốn một biểu tượng bên cạnh mỗi dòng, nhưng chỉ bên cạnh dòng đầu tiên của mỗi nhóm ...

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

Tôi không nghĩ rằng tôi có thể cung cấp cho bạn một câu trả lời đầy đủ, thật không may, tuy nhiên tôi có thể chỉ cho bạn theo hướng mà bạn sẽ ít nhất cần phải hiểu IAdornmentLayer (đó là cách bạn vẽ trên đầu trang của xem). Chế độ xem chính là một loại IWpfTextView. Đó là một phần để vẽ biểu tượng thực tế trên màn hình. Tìm ra vị trí chính xác mà tôi không thể giúp bạn bởi vì tôi không biết làm thế nào để khám phá phía trên bên phải của khối xml-comment, hãy để một mình ở trên phương thức/field/property/class/etc. –

+0

tại sao bạn cần một NormalizedSnapshotSpanCollection ?? Bạn có biết bạn có thể nhận được từ IWpfTextView tất cả các dòng cho bộ đệm trình biên tập hiện tại hay không, và sử dụng một regex đơn giản tìm tất cả khớp với ///

bất kỳ dòng nào. hàng? –

+0

Không, tôi không biết gì về điều đó. Tôi chỉ thấy một ví dụ sử dụng một NormalizedSnapshotSpancollection vì vậy tôi nghĩ rằng tôi cần ... về cơ bản, bất cứ điều gì sẽ cho tôi tọa độ tôi cần mà không có dương tính giả để tôi có thể đặt một biểu tượng lên nơi mong muốn. – michael

Trả lời

12

Đây là những gì tôi có thể nhận được, Tôi nghĩ nó khá giống với những gì bạn cần. Tôi sẽ cập nhật thông tin này với nhiều chi tiết hơn nếu bạn có câu hỏi.

VS 2010 icon adornment

tôi bắt đầu với this sample từ VS 2010 trang web SDK. Nó đã được khá gần với những gì bạn cần, nhưng đòi hỏi một vài bước nữa.


Tải xuống phiên bản C#, giải nén vào thư mục, biên dịch. Để chạy nó và kiểm tra bạn cần phải đi đến Project> Properties> Debug

Bạn cần phải chọn "Chương trình ngoài Start" tùy chọn và thiết lập đường dẫn đến ứng dụng VS 2010 của bạn, ví dụ C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe

Trong các đối số dòng lệnh set: /rootsuffix Exp

Bây giờ bạn có thể chạy nó, tạo một số dự án mẫu trong VS đã mở và nếu bạn nhập bất kỳ số nào có sáu chữ số như 00AA00, nó sẽ được hiển thị dưới dạng hình chữ nhật có màu tương ứng. Đóng ví dụ gỡ lỗi VS.


Bây giờ, hãy chỉnh sửa một số mã. Trong ColorAdornmentTagger.cs hãy nhận xét định nghĩa #define HIDING_TEXT. Điều này sẽ hiển thị các trang sức bên cạnh văn bản, chứ không phải thay vì nó.

Trong cùng một tập tin bạn cần phải tìm nơi SnapshotSpan adornmentSpan được khởi tạo và thay đổi dòng để:

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

này sẽ đặt trang sức sau span văn bản, không phải trước đó.


Trong ColorTagger.cs. Thay đổi regex trong hàm tạo, vì vậy hàm tạo bây giờ trông giống như

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

Điều này sẽ thiết lập regex để nhận dạng dòng chú giải phương thức.

Các phương pháp khác trong lớp này, chúng tôi sẽ không sử dụng, bạn có thể nhận xét hoặc trả về một số màu ngẫu nhiên.


Trong 'ColorAdornment.cs'. Đây là điều khiển WPF trang nghiêm. Đầu tiên thay đổi lớp cơ sở từ Button thành ContentControl. Thay đổi hàm tạo của lớp thành

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

Bạn có thể thay đổi đường dẫn hình ảnh theo đường dẫn hình ảnh bạn cần.Tôi vừa tải xuống logo SO từ Wikipedia và đưa vào thư mục tạm thời của tôi.

Biên dịch và chạy. Bạn sẽ có thể thấy logo SO bên cạnh các chú thích trong ví dụ gỡ lỗi VS.


Một số nhận xét bổ sung.

Đầu tiên, theo cách này, bạn chỉ cần lấy nguyên mẫu làm việc để bắt đầu, bạn nên đổi tên các lớp và dọn sạch mã cho nhu cầu của mình.

Thứ hai, khi tôi gỡ lỗi, lỗi gỡ lỗi của tôi VS đã bị đóng băng theo thời gian. Tôi nghĩ rằng điều này có thể liên quan đến ổ khóa trong IntraTextAdornmentTagger.cs

Nếu bạn cũng thấy đông, cố gắng cập nhật các phương pháp sau đây theo cách này:

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

và AsyncUpdate theo cách này:

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

Vâng, đó chắc chắn là một điểm khởi đầu tốt. Tôi đã hy vọng cho một số thuật toán để phát hiện rằng một khối bình luận là trên một lớp hợp lệ, enum, struct, tài sản, lĩnh vực, phương pháp, vv nhưng điều này là gần như tôi sẽ nhận được cho bây giờ tôi nghĩ. Nó có một số lỗ hổng trong thực tế là nó dựa vào '///

*' bởi vì tôi có thể đặt ở nơi khác và nhận được các kết quả sai (tôi biết nó không có ý nghĩa để làm điều đó). Dù bằng cách nào, toàn bộ 20000 để giúp đỡ rất nhiều. – michael

+0

Ngoài ra, tại sao tôi cần tham số '/ rootsuffix Exp' cho lệnh gọi devenv.exe? – michael

+0

@michael: Cảm ơn! '/ Rootsuffix Exp' là để bảo vệ VS mặc định khỏi thử nghiệm của bạn http://msdn.microsoft.com/en-us/library/bb166560(v=VS.80).aspx –

Các vấn đề liên quan