İzlenecek yol: Düzenleyici uzantısıyla kabuk komutu kullanma
VSPackage'dan düzenleyiciye menü komutları gibi özellikler ekleyebilirsiniz. Bu kılavuzda, bir menü komutu çağırarak düzenleyicideki metin görünümüne nasıl kenarlık ekleneceği gösterilir.
Bu izlenecek yol, YÖNETILEN Genişletilebilirlik Çerçevesi (MEF) bileşen bölümüyle birlikte VSPackage kullanımını gösterir. Menü komutunu Visual Studio kabuğuna kaydetmek için VSPackage kullanmanız gerekir. Ayrıca komutunu kullanarak MEF bileşeni bölümüne erişebilirsiniz.
Menü komutuyla uzantı oluşturma
Araçlar menüsüne Donatma Ekle adlı bir menü komutu koyan bir VSPackage oluşturun.
adlı
MenuCommandTest
bir C# VSIX projesi oluşturun ve AddAdornment adlı bir Özel Komut öğesi şablonu adı ekleyin. Daha fazla bilgi için bkz . Menü komutuyla uzantı oluşturma.MenuCommandTest adlı bir çözüm açılır. MenuCommandTestPackage dosyasında menü komutunu oluşturan ve Araçlar menüsüne yerleştiren kod bulunur. Bu noktada, komut yalnızca bir ileti kutusunun görünmesine neden olur. Sonraki adımlarda, açıklama süslemesini görüntülemek için bunun nasıl değiştirileceği gösterilir.
SOURCE.extension.vsixmanifest dosyasını VSIX Bildirim Düzenleyicisi'nde açın. Sekmede
Assets
MenuCommandTest adlı bir Microsoft.VisualStudio.VsPackage satırı olmalıdır.source.extension.vsixmanifest dosyasını kaydedin ve kapatın.
Komut uzantısına MEF uzantısı ekleme
Çözüm Gezgini çözüm düğümüne sağ tıklayın, Ekle'ye ve ardından Yeni Proje'ye tıklayın. Yeni Proje Ekle iletişim kutusunda, Visual C# altında Genişletilebilirlik'e ve ardından VSIX Projesi'ne tıklayın. Projeyi
CommentAdornmentTest
olarak adlandırın.Bu proje, tanımlayıcı adlı VSPackage derlemesiyle etkileşimde bulunacağından, derlemeyi imzalamanız gerekir. VSPackage derlemesi için önceden oluşturulmuş anahtar dosyasını yeniden kullanabilirsiniz.
Proje özelliklerini açın ve İmzalama sekmesini seçin.
Derlemeyi imzala'ya tıklayın.
Kesin ad anahtar dosyası seçin altında MenuCommandTest derlemesi için oluşturulan Key.snk dosyasını seçin.
VSPackage projesinde MEF uzantısına bakın
VSPackage'a bir MEF bileşeni eklediğinizden bildirimde her iki varlık türünü de belirtmeniz gerekir.
Not
MEF hakkında daha fazla bilgi için bkz . Yönetilen Genişletilebilirlik Çerçevesi (MEF).
VSPackage projesindeki MEF bileşenine başvurmak için
MenuCommandTest projesinde , VSIX Bildirim Düzenleyicisi'nde source.extension.vsixmanifest dosyasını açın.
Varlıklar sekmesinde Yeni'ye tıklayın.
Tür listesinde Microsoft.VisualStudio.MefComponent öğesini seçin.
Kaynak listesinde Geçerli çözümde bir proje'yi seçin.
Proje listesinde CommentAdornmentTest'i seçin.
source.extension.vsixmanifest dosyasını kaydedin ve kapatın.
MenuCommandTest projesinin CommentAdornmentTest projesine bir başvurusu olduğundan emin olun.
CommentAdornmentTest projesinde, projeyi bir derleme oluşturacak şekilde ayarlayın. Çözüm Gezgini projeyi seçin ve Özellikler penceresine Bakarak Derleme Çıktısını OutputDirectory'ye Kopyala özelliğini arayın ve true olarak ayarlayın.
Açıklama süslemesi tanımlama
Açıklama süslemesi, seçilen metni izleyen bir ITrackingSpan öğeden ve yazarı ve metnin açıklamasını temsil eden bazı dizelerden oluşur.
Açıklama süslemesi tanımlamak için
CommentAdornmentTest projesinde yeni bir sınıf dosyası ekleyin ve olarak adlandırın
CommentAdornment
.Aşağıdaki başvuruları ekleyin:
Microsoft.VisualStudio.CoreUtility
Microsoft.VisualStudio.Text.Data
Microsoft.VisualStudio.Text.Logic
Microsoft.VisualStudio.Text.UI
Microsoft.VisualStudio.Text.UI.Wpf
System.ComponentModel.Composition
Presentationcore
Presentationframework
Windowsbase
Aşağıdaki
using
yönergeyi ekleyin.using Microsoft.VisualStudio.Text;
dosya adlı
CommentAdornment
bir sınıf içermelidir.internal class CommentAdornment
sınıfına
CommentAdornment
, yazarı ve açıklaması için ITrackingSpanüç alan ekleyin.public readonly ITrackingSpan Span; public readonly string Author; public readonly string Text;
Alanları başlatan bir oluşturucu ekleyin.
public CommentAdornment(SnapshotSpan span, string author, string text) { this.Span = span.Snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeExclusive); this.Author = author; this.Text = text; }
Donatma için görsel öğe oluşturma
Süslemeniz için görsel bir öğe tanımlayın. Bu kılavuz için, Windows Presentation Foundation (WPF) sınıfından Canvasdevralan bir denetim tanımlayın.
CommentAdornmentTest projesinde bir sınıf oluşturun ve olarak adlandırın
CommentBlock
.Aşağıdaki
using
yönergeleri ekleyin.using Microsoft.VisualStudio.Text; using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; using System.ComponentModel.Composition; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Utilities;
sınıfını
CommentBlock
öğesinden Canvasdevralın.internal class CommentBlock : Canvas { }
Süslemenin görsel yönlerini tanımlamak için bazı özel alanlar ekleyin.
private Geometry textGeometry; private Grid commentGrid; private static Brush brush; private static Pen solidPen; private static Pen dashPen;
Açıklama süslemesini tanımlayan ve ilgili metni ekleyen bir oluşturucu ekleyin.
public CommentBlock(double textRightEdge, double viewRightEdge, Geometry newTextGeometry, string author, string body) { if (brush == null) { brush = new SolidColorBrush(Color.FromArgb(0x20, 0x00, 0xff, 0x00)); brush.Freeze(); Brush penBrush = new SolidColorBrush(Colors.Green); penBrush.Freeze(); solidPen = new Pen(penBrush, 0.5); solidPen.Freeze(); dashPen = new Pen(penBrush, 0.5); dashPen.DashStyle = DashStyles.Dash; dashPen.Freeze(); } this.textGeometry = newTextGeometry; TextBlock tb1 = new TextBlock(); tb1.Text = author; TextBlock tb2 = new TextBlock(); tb2.Text = body; const int MarginWidth = 8; this.commentGrid = new Grid(); this.commentGrid.RowDefinitions.Add(new RowDefinition()); this.commentGrid.RowDefinitions.Add(new RowDefinition()); ColumnDefinition cEdge = new ColumnDefinition(); cEdge.Width = new GridLength(MarginWidth); ColumnDefinition cEdge2 = new ColumnDefinition(); cEdge2.Width = new GridLength(MarginWidth); this.commentGrid.ColumnDefinitions.Add(cEdge); this.commentGrid.ColumnDefinitions.Add(new ColumnDefinition()); this.commentGrid.ColumnDefinitions.Add(cEdge2); System.Windows.Shapes.Rectangle rect = new System.Windows.Shapes.Rectangle(); rect.RadiusX = 6; rect.RadiusY = 3; rect.Fill = brush; rect.Stroke = Brushes.Green; Size inf = new Size(double.PositiveInfinity, double.PositiveInfinity); tb1.Measure(inf); tb2.Measure(inf); double middleWidth = Math.Max(tb1.DesiredSize.Width, tb2.DesiredSize.Width); this.commentGrid.Width = middleWidth + 2 * MarginWidth; Grid.SetColumn(rect, 0); Grid.SetRow(rect, 0); Grid.SetRowSpan(rect, 2); Grid.SetColumnSpan(rect, 3); Grid.SetRow(tb1, 0); Grid.SetColumn(tb1, 1); Grid.SetRow(tb2, 1); Grid.SetColumn(tb2, 1); this.commentGrid.Children.Add(rect); this.commentGrid.Children.Add(tb1); this.commentGrid.Children.Add(tb2); Canvas.SetLeft(this.commentGrid, Math.Max(viewRightEdge - this.commentGrid.Width - 20.0, textRightEdge + 20.0)); Canvas.SetTop(this.commentGrid, textGeometry.GetRenderBounds(solidPen).Top); this.Children.Add(this.commentGrid); }
Ayrıca, süslemeyi çizen bir OnRender olay işleyicisi de uygulayın.
protected override void OnRender(DrawingContext dc) { base.OnRender(dc); if (this.textGeometry != null) { dc.DrawGeometry(brush, solidPen, this.textGeometry); Rect textBounds = this.textGeometry.GetRenderBounds(solidPen); Point p1 = new Point(textBounds.Right, textBounds.Bottom); Point p2 = new Point(Math.Max(Canvas.GetLeft(this.commentGrid) - 20.0, p1.X), p1.Y); Point p3 = new Point(Math.Max(Canvas.GetLeft(this.commentGrid), p1.X), (Canvas.GetTop(this.commentGrid) + p1.Y) * 0.5); dc.DrawLine(dashPen, p1, p2); dc.DrawLine(dashPen, p2, p3); } }
IWpfTextViewCreationListener ekleme
IWpfTextViewCreationListener, oluşturma olaylarını görüntülemek için kullanabileceğiniz bir MEF bileşeni bölümüdür.
CommentAdornmentTest projesine bir sınıf dosyası ekleyin ve olarak adlandırın
Connector
.Aşağıdaki
using
yönergeleri ekleyin.using System.ComponentModel.Composition; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Utilities;
uygulayan IWpfTextViewCreationListenerbir sınıf bildirin ve bunu bir "text" ve bir TextViewRoleAttribute ile dışarı ContentTypeAttribute aktarınDocument. İçerik türü özniteliği, bileşenin uygulandığı içerik türünü belirtir. Metin türü, ikili olmayan tüm dosya türlerinin temel türüdür. Bu nedenle, oluşturulan hemen hemen her metin görünümü bu türde olacaktır. Metin görünümü rol özniteliği, bileşenin uygulandığı metin görünümünün türünü belirtir. Belge metin görünümü rolleri genellikle satırlardan oluşan ve bir dosyada depolanan metni gösterir.
yöntemini uygulayarak TextViewCreated statik olayını çağırmasını
Create()
sağlayınCommentAdornmentManager
.public void TextViewCreated(IWpfTextView textView) { CommentAdornmentManager.Create(textView); }
Komutunu yürütmek için kullanabileceğiniz bir yöntem ekleyin.
static public void Execute(IWpfTextViewHost host) { IWpfTextView view = host.TextView; //Add a comment on the selected text. if (!view.Selection.IsEmpty) { //Get the provider for the comment adornments in the property bag of the view. CommentAdornmentProvider provider = view.Properties.GetProperty<CommentAdornmentProvider>(typeof(CommentAdornmentProvider)); //Add some arbitrary author and comment text. string author = System.Security.Principal.WindowsIdentity.GetCurrent().Name; string comment = "Four score...."; //Add the comment adornment using the provider. provider.Add(view.Selection.SelectedSpans[0], author, comment); } }
Bir donatma katmanı tanımlama
Yeni bir kenarlık eklemek için bir donatma katmanı tanımlamanız gerekir.
Bir donatma katmanı tanımlamak için
Connector
sınıfında, türünde AdornmentLayerDefinitionbir genel alan bildirin ve bunu, donatma katmanı için benzersiz bir ad belirten ve bu süsleme katmanının OrderAttribute diğer metin görünümü katmanlarıyla (metin, şapka işareti ve seçim) Z sırası ilişkisini tanımlayan bir ile NameAttribute dışarı aktarın.[Export(typeof(AdornmentLayerDefinition))] [Name("CommentAdornmentLayer")] [Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)] public AdornmentLayerDefinition commentLayerDefinition;
Açıklama süslemeleri sağlama
Bir donatma tanımladığınızda, bir açıklama süsleme sağlayıcısı ve açıklama süsleme yöneticisi de uygulayın. Açıklama süsleme sağlayıcısı açıklama kenarlıklarının listesini tutar, temel alınan metin arabelleğindeki olayları dinler Changed ve temel alınan metin silindiğinde açıklama kenarlıklarını siler.
CommentAdornmentTest projesine yeni bir sınıf dosyası ekleyin ve olarak adlandırın
CommentAdornmentProvider
.Aşağıdaki
using
yönergeleri ekleyin.using System; using System.Collections.Generic; using System.Collections.ObjectModel; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor;
adlı
CommentAdornmentProvider
bir sınıf ekleyin.internal class CommentAdornmentProvider { }
Metin arabelleği için özel alanlar ve arabellekle ilgili açıklama kenarlıkları listesi ekleyin.
private ITextBuffer buffer; private IList<CommentAdornment> comments = new List<CommentAdornment>();
için
CommentAdornmentProvider
bir oluşturucu ekleyin. Sağlayıcı yöntemiyle örneklendiğinden, bu oluşturucu özel erişimeCreate()
sahip olmalıdır. Oluşturucu, olay işleyicisiniOnBufferChanged
Changed olaya ekler.private CommentAdornmentProvider(ITextBuffer buffer) { this.buffer = buffer; //listen to the Changed event so we can react to deletions. this.buffer.Changed += OnBufferChanged; }
Create()
yöntemini ekleyin.public static CommentAdornmentProvider Create(IWpfTextView view) { return view.Properties.GetOrCreateSingletonProperty<CommentAdornmentProvider>(delegate { return new CommentAdornmentProvider(view.TextBuffer); }); }
Detach()
yöntemini ekleyin.public void Detach() { if (this.buffer != null) { //remove the Changed listener this.buffer.Changed -= OnBufferChanged; this.buffer = null; } }
Olay işleyicisini
OnBufferChanged
ekleyin.private void OnBufferChanged(object sender, TextContentChangedEventArgs e) { //Make a list of all comments that have a span of at least one character after applying the change. There is no need to raise a changed event for the deleted adornments. The adornments are deleted only if a text change would cause the view to reformat the line and discard the adornments. IList<CommentAdornment> keptComments = new List<CommentAdornment>(this.comments.Count); foreach (CommentAdornment comment in this.comments) { Span span = comment.Span.GetSpan(e.After); //if a comment does not span at least one character, its text was deleted. if (span.Length != 0) { keptComments.Add(comment); } } this.comments = keptComments; }
Bir olay için bildirim
CommentsChanged
ekleyin.public event EventHandler<CommentsChangedEventArgs> CommentsChanged;
Donatma eklemek için bir
Add()
yöntem oluşturun.public void Add(SnapshotSpan span, string author, string text) { if (span.Length == 0) throw new ArgumentOutOfRangeException("span"); if (author == null) throw new ArgumentNullException("author"); if (text == null) throw new ArgumentNullException("text"); //Create a comment adornment given the span, author and text. CommentAdornment comment = new CommentAdornment(span, author, text); //Add it to the list of comments. this.comments.Add(comment); //Raise the changed event. EventHandler<CommentsChangedEventArgs> commentsChanged = this.CommentsChanged; if (commentsChanged != null) commentsChanged(this, new CommentsChangedEventArgs(comment, null)); }
Bir
RemoveComments()
yöntem ekleyin.public void RemoveComments(SnapshotSpan span) { EventHandler<CommentsChangedEventArgs> commentsChanged = this.CommentsChanged; //Get a list of all the comments that are being kept IList<CommentAdornment> keptComments = new List<CommentAdornment>(this.comments.Count); foreach (CommentAdornment comment in this.comments) { //find out if the given span overlaps with the comment text span. If two spans are adjacent, they do not overlap. To consider adjacent spans, use IntersectsWith. if (comment.Span.GetSpan(span.Snapshot).OverlapsWith(span)) { //Raise the change event to delete this comment. if (commentsChanged != null) commentsChanged(this, new CommentsChangedEventArgs(null, comment)); } else keptComments.Add(comment); } this.comments = keptComments; }
Belirli bir
GetComments()
anlık görüntü aralığındaki tüm açıklamaları döndüren bir yöntem ekleyin.public Collection<CommentAdornment> GetComments(SnapshotSpan span) { IList<CommentAdornment> overlappingComments = new List<CommentAdornment>(); foreach (CommentAdornment comment in this.comments) { if (comment.Span.GetSpan(span.Snapshot).OverlapsWith(span)) overlappingComments.Add(comment); } return new Collection<CommentAdornment>(overlappingComments); }
aşağıdaki gibi adlı
CommentsChangedEventArgs
bir sınıf ekleyin.internal class CommentsChangedEventArgs : EventArgs { public readonly CommentAdornment CommentAdded; public readonly CommentAdornment CommentRemoved; public CommentsChangedEventArgs(CommentAdornment added, CommentAdornment removed) { this.CommentAdded = added; this.CommentRemoved = removed; } }
Açıklama süslemelerini yönetme
Açıklama süsleme yöneticisi, süslemeyi oluşturur ve bunu donatma katmanına ekler. Ve Closed olaylarını dinlerLayoutChanged, böylece süslemeyi taşıyabilir veya silebilir. Ayrıca açıklamalar CommentsChanged
eklendiğinde veya kaldırıldığında açıklama donatma sağlayıcısı tarafından tetiklenen olayı dinler.
CommentAdornmentTest projesine bir sınıf dosyası ekleyin ve olarak adlandırın
CommentAdornmentManager
.Aşağıdaki
using
yönergeleri ekleyin.using System; using System.Collections.Generic; using System.Windows.Media; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Formatting;
adlı
CommentAdornmentManager
bir sınıf ekleyin.internal class CommentAdornmentManager { }
Bazı özel alanlar ekleyin.
private readonly IWpfTextView view; private readonly IAdornmentLayer layer; private readonly CommentAdornmentProvider provider;
Yöneticisini LayoutChanged ve Closed olaylarına ve ayrıca
CommentsChanged
olaya abone olan bir oluşturucu ekleyin. Yönetici statikCreate()
yöntem tarafından örneklendiğinden oluşturucu özeldir.private CommentAdornmentManager(IWpfTextView view) { this.view = view; this.view.LayoutChanged += OnLayoutChanged; this.view.Closed += OnClosed; this.layer = view.GetAdornmentLayer("CommentAdornmentLayer"); this.provider = CommentAdornmentProvider.Create(view); this.provider.CommentsChanged += OnCommentsChanged; }
Sağlayıcıyı
Create()
alan veya gerekirse bir sağlayıcı oluşturan yöntemi ekleyin.public static CommentAdornmentManager Create(IWpfTextView view) { return view.Properties.GetOrCreateSingletonProperty<CommentAdornmentManager>(delegate { return new CommentAdornmentManager(view); }); }
İşleyiciyi
CommentsChanged
ekleyin.private void OnCommentsChanged(object sender, CommentsChangedEventArgs e) { //Remove the comment (when the adornment was added, the comment adornment was used as the tag). if (e.CommentRemoved != null) this.layer.RemoveAdornmentsByTag(e.CommentRemoved); //Draw the newly added comment (this will appear immediately: the view does not need to do a layout). if (e.CommentAdded != null) this.DrawComment(e.CommentAdded); }
İşleyiciyi Closed ekleyin.
private void OnClosed(object sender, EventArgs e) { this.provider.Detach(); this.view.LayoutChanged -= OnLayoutChanged; this.view.Closed -= OnClosed; }
İşleyiciyi LayoutChanged ekleyin.
private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e) { //Get all of the comments that intersect any of the new or reformatted lines of text. List<CommentAdornment> newComments = new List<CommentAdornment>(); //The event args contain a list of modified lines and a NormalizedSpanCollection of the spans of the modified lines. //Use the latter to find the comments that intersect the new or reformatted lines of text. foreach (Span span in e.NewOrReformattedSpans) { newComments.AddRange(this.provider.GetComments(new SnapshotSpan(this.view.TextSnapshot, span))); } //It is possible to get duplicates in this list if a comment spanned 3 lines, and the first and last lines were modified but the middle line was not. //Sort the list and skip duplicates. newComments.Sort(delegate(CommentAdornment a, CommentAdornment b) { return a.GetHashCode().CompareTo(b.GetHashCode()); }); CommentAdornment lastComment = null; foreach (CommentAdornment comment in newComments) { if (comment != lastComment) { lastComment = comment; this.DrawComment(comment); } } }
Açıklamayı çizen özel yöntemi ekleyin.
private void DrawComment(CommentAdornment comment) { SnapshotSpan span = comment.Span.GetSpan(this.view.TextSnapshot); Geometry g = this.view.TextViewLines.GetMarkerGeometry(span); if (g != null) { //Find the rightmost coordinate of all the lines that intersect the adornment. double maxRight = 0.0; foreach (ITextViewLine line in this.view.TextViewLines.GetTextViewLinesIntersectingSpan(span)) maxRight = Math.Max(maxRight, line.Right); //Create the visualization. CommentBlock block = new CommentBlock(maxRight, this.view.ViewportRight, g, comment.Author, comment.Text); //Add it to the layer. this.layer.AddAdornment(span, comment, block); } }
Açıklama süslemesini eklemek için menü komutunu kullanın
VSPackage yöntemini uygulayarak MenuItemCallback
açıklama süslemesi oluşturmak için menü komutunu kullanabilirsiniz.
MenuCommandTest projesine aşağıdaki başvuruları ekleyin:
Microsoft.VisualStudio.TextManager.Interop
Microsoft.VisualStudio.Editor
Microsoft.VisualStudio.Text.UI.Wpf
AddAdornment.cs dosyasını açın ve aşağıdaki
using
yönergeleri ekleyin.using Microsoft.VisualStudio.TextManager.Interop; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Editor; using CommentAdornmentTest;
Execute()
yöntemini silin ve aşağıdaki komut işleyicisini ekleyin.private async void AddAdornmentHandler(object sender, EventArgs e) { }
Etkin görünümü almak için kod ekleyin. Etkin
IVsTextView
öğesini almakSVsTextManager
için Visual Studio kabuğunu almanız gerekir.private async void AddAdornmentHandler(object sender, EventArgs e) { IVsTextManager txtMgr = (IVsTextManager) await ServiceProvider.GetServiceAsync(typeof(SVsTextManager)); IVsTextView vTextView = null; int mustHaveFocus = 1; txtMgr.GetActiveView(mustHaveFocus, null, out vTextView); }
Bu metin görünümü bir düzenleyici metin görünümünün örneğiyse, bunu arabirime IVsUserData yayınlayabilir ve ardından ve ilişkili IWpfTextViewöğesini alabilirsinizIWpfTextViewHost. IWpfTextViewHost yöntemini çağırmak
Connector.Execute()
için kullanın. Bu yöntem, açıklama donatı sağlayıcısını alır ve donatıyı ekler. Komut işleyicisi artık şu kod gibi görünmelidir:private async void AddAdornmentHandler(object sender, EventArgs e) { IVsTextManager txtMgr = (IVsTextManager) await ServiceProvider.GetServiceAsync(typeof(SVsTextManager)); IVsTextView vTextView = null; int mustHaveFocus = 1; txtMgr.GetActiveView(mustHaveFocus, null, out vTextView); IVsUserData userData = vTextView as IVsUserData; if (userData == null) { Console.WriteLine("No text view is currently open"); return; } IWpfTextViewHost viewHost; object holder; Guid guidViewHost = DefGuidList.guidIWpfTextViewHost; userData.GetData(ref guidViewHost, out holder); viewHost = (IWpfTextViewHost)holder; Connector.Execute(viewHost); }
AddAdornmentHandler yöntemini AddAdornment oluşturucusunda AddAdornment komutunun işleyicisi olarak ayarlayın.
private AddAdornment(AsyncPackage package, OleMenuCommandService commandService) { this.package = package ?? throw new ArgumentNullException(nameof(package)); commandService = commandService ?? throw new ArgumentNullException(nameof(commandService)); var menuCommandID = new CommandID(CommandSet, CommandId); var menuItem = new MenuCommand(this.AddAdornmentHandler, menuCommandID); commandService.AddCommand(menuItem); }
Kodu derleme ve test etme
Çözümü derleyin ve hata ayıklamaya başlayın. Deneysel örnek görünmelidir.
Bir metin dosyası oluşturun. Metin yazıp seçin.
Araçlar menüsünde, Donatma Ekle'yi Çağır'a tıklayın. Balon, metin penceresinin sağ tarafında görüntülenmeli ve aşağıdaki metne benzeyen bir metin içermelidir.
Kullanıcı Adınız
Dört çekirdekli...