Panduan: Menampilkan saran bola lampu
Bola lampu adalah ikon di editor Visual Studio yang diperluas untuk menampilkan serangkaian tindakan, misalnya, perbaikan untuk masalah yang diidentifikasi oleh penganalisis kode bawaan atau pemfaktoran ulang kode.
Di editor Visual C# dan Visual Basic, Anda juga dapat menggunakan .NET Compiler Platform ("Roslyn") untuk menulis dan mengemas penganalisis kode Anda sendiri dengan tindakan yang menampilkan bola lampu secara otomatis. Untuk informasi selengkapnya, lihat:
Cara: Menulis diagnostik Visual Basic dan perbaikan kode
Bahasa lain seperti C++ juga menyediakan bola lampu untuk beberapa tindakan cepat, seperti, saran untuk membuat implementasi stub dari fungsi tersebut.
Seperti inilah bola lampu terlihat. Dalam proyek Visual Basic atau Visual C#, squiggle merah muncul di bawah nama variabel saat tidak valid. Jika Anda mengarahkan mouse ke pengidentifikasi yang tidak valid, bola lampu muncul di dekat kursor.
Jika Anda mengklik panah bawah oleh bola lampu, sekumpulan tindakan yang disarankan muncul, bersama dengan pratinjau tindakan yang dipilih. Dalam hal ini, ini menunjukkan perubahan yang dibuat pada kode Anda jika Anda menjalankan tindakan.
Anda dapat menggunakan bola lampu untuk memberikan tindakan yang anda sarankan sendiri. Misalnya, Anda dapat memberikan tindakan untuk memindahkan kurung kurawal pembuka ke baris baru atau memindahkannya ke akhir baris sebelumnya. Panduan berikut menunjukkan cara membuat bola lampu yang muncul pada kata saat ini dan memiliki dua tindakan yang disarankan: Konversi ke huruf besar dan Konversi ke huruf kecil.
Membuat proyek Managed Extensibility Framework (MEF)
Buat proyek C# VSIX. (Dalam Dialog Proyek Baru, pilih Visual C# / Ekstensibilitas, lalu Proyek VSIX.) Beri nama solusi
LightBulbTest
.Tambahkan templat item Pengklasifikasi Editor ke proyek. Untuk informasi selengkapnya, lihat Membuat ekstensi dengan templat item editor.
Hapus file kelas yang ada.
Tambahkan referensi berikut ke proyek, dan atur Salin Lokal ke
False
:Microsoft.VisualStudio.Language.Intellisense
Tambahkan file kelas baru dan beri nama LightBulbTest.
Tambahkan hal berikut menggunakan instruksi:
using System; using System.Linq; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Utilities; using System.ComponentModel.Composition; using System.Threading;
Menerapkan penyedia sumber bola lampu
Dalam file kelas LightBulbTest.cs, hapus kelas LightBulbTest. Tambahkan kelas bernama TestSuggestedActionsSourceProvider yang mengimplementasikan ISuggestedActionsSourceProvider. Ekspor dengan Nama Tindakan yang Disarankan Pengujian dan ContentTypeAttribute "teks".
[Export(typeof(ISuggestedActionsSourceProvider))] [Name("Test Suggested Actions")] [ContentType("text")] internal class TestSuggestedActionsSourceProvider : ISuggestedActionsSourceProvider
Di dalam kelas penyedia sumber, impor ITextStructureNavigatorSelectorService dan tambahkan sebagai properti.
[Import(typeof(ITextStructureNavigatorSelectorService))] internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
Terapkan CreateSuggestedActionsSource metode untuk mengembalikan ISuggestedActionsSource objek. Sumber dibahas di bagian berikutnya.
public ISuggestedActionsSource CreateSuggestedActionsSource(ITextView textView, ITextBuffer textBuffer) { if (textBuffer == null || textView == null) { return null; } return new TestSuggestedActionsSource(this, textView, textBuffer); }
Menerapkan ISuggestedActionSource
Sumber tindakan yang disarankan bertanggung jawab untuk mengumpulkan serangkaian tindakan yang disarankan dan menambahkannya dalam konteks yang tepat. Dalam hal ini, konteksnya adalah kata saat ini dan tindakan yang disarankan adalah UpperCaseSuggestedAction dan LowerCaseSuggestedAction, yang dibahas di bagian berikut.
Tambahkan kelas TestSuggestedActionsSource yang mengimplementasikan ISuggestedActionsSource.
internal class TestSuggestedActionsSource : ISuggestedActionsSource
Tambahkan bidang privat baca-saja untuk penyedia sumber tindakan yang disarankan, buffer teks, dan tampilan teks.
private readonly TestSuggestedActionsSourceProvider m_factory; private readonly ITextBuffer m_textBuffer; private readonly ITextView m_textView;
Tambahkan konstruktor yang mengatur bidang privat.
public TestSuggestedActionsSource(TestSuggestedActionsSourceProvider testSuggestedActionsSourceProvider, ITextView textView, ITextBuffer textBuffer) { m_factory = testSuggestedActionsSourceProvider; m_textBuffer = textBuffer; m_textView = textView; }
Tambahkan metode privat yang mengembalikan kata yang saat ini berada di bawah kursor. Metode berikut melihat lokasi kursor saat ini dan meminta navigator struktur teks sejauh mana kata tersebut. Jika kursor ada pada kata, TextExtent dikembalikan dalam parameter keluar; jika tidak,
out
parameter adalahnull
dan metode mengembalikanfalse
.private bool TryGetWordUnderCaret(out TextExtent wordExtent) { ITextCaret caret = m_textView.Caret; SnapshotPoint point; if (caret.Position.BufferPosition > 0) { point = caret.Position.BufferPosition - 1; } else { wordExtent = default(TextExtent); return false; } ITextStructureNavigator navigator = m_factory.NavigatorService.GetTextStructureNavigator(m_textBuffer); wordExtent = navigator.GetExtentOfWord(point); return true; }
Mengimplementasikan metode HasSuggestedActionsAsync. Editor memanggil metode ini untuk mengetahui apakah akan menampilkan bola lampu. Panggilan ini sering dilakukan, misalnya, setiap kali kursor bergerak dari satu baris ke baris lain, atau ketika mouse mengarahkan kursor ke kesalahan berlekuk. Ini asinkron untuk memungkinkan operasi UI lain untuk dilaksanakan saat metode ini berfungsi. Dalam kebanyakan kasus, metode ini perlu melakukan beberapa penguraian dan analisis baris saat ini, sehingga pemrosesan mungkin memakan waktu.
Dalam implementasi ini, secara asinkron mendapatkan TextExtent dan menentukan apakah tingkatnya signifikan, seperti dalam, apakah ia memiliki beberapa teks selain spasi putih.
public Task<bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { return Task.Factory.StartNew(() => { TextExtent extent; if (TryGetWordUnderCaret(out extent)) { // don't display the action if the extent has whitespace return extent.IsSignificant; } return false; }); }
Terapkan GetSuggestedActions metode , yang mengembalikan array SuggestedActionSet objek yang berisi objek yang berbeda ISuggestedAction . Metode ini dipanggil ketika bola lampu diperluas.
Peringatan
Anda harus memastikan bahwa implementasi
HasSuggestedActionsAsync()
danGetSuggestedActions()
konsisten; yaitu, jikaHasSuggestedActionsAsync()
mengembalikantrue
, makaGetSuggestedActions()
harus memiliki beberapa tindakan untuk ditampilkan. Dalam banyak kasus,HasSuggestedActionsAsync()
dipanggil tepat sebelumGetSuggestedActions()
, tetapi ini tidak selalu terjadi. Misalnya, jika pengguna memanggil tindakan bola lampu dengan menekan (CTRL+ .) hanyaGetSuggestedActions()
dipanggil.public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) { TextExtent extent; if (TryGetWordUnderCaret(out extent) && extent.IsSignificant) { ITrackingSpan trackingSpan = range.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive); var upperAction = new UpperCaseSuggestedAction(trackingSpan); var lowerAction = new LowerCaseSuggestedAction(trackingSpan); return new SuggestedActionSet[] { new SuggestedActionSet(new ISuggestedAction[] { upperAction, lowerAction }) }; } return Enumerable.Empty<SuggestedActionSet>(); }
SuggestedActionsChanged
Tentukan peristiwa.public event EventHandler<EventArgs> SuggestedActionsChanged;
Untuk menyelesaikan implementasi, tambahkan implementasi untuk
Dispose()
metode danTryGetTelemetryId()
. Anda tidak ingin melakukan telemetri, jadi kembalikanfalse
saja dan atur GUID keEmpty
.public void Dispose() { } public bool TryGetTelemetryId(out Guid telemetryId) { // This is a sample provider and doesn't participate in LightBulb telemetry telemetryId = Guid.Empty; return false; }
Menerapkan tindakan bola lampu
Dalam proyek, tambahkan referensi ke Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll dan atur Salin Lokal ke
False
.Buat dua kelas, yang pertama bernama
UpperCaseSuggestedAction
dan yang kedua bernamaLowerCaseSuggestedAction
. Kedua kelas mengimplementasikan ISuggestedAction.internal class UpperCaseSuggestedAction : ISuggestedAction internal class LowerCaseSuggestedAction : ISuggestedAction
Kedua kelas sama kecuali satu panggilan ToUpper dan panggilan ToLowerlainnya . Langkah-langkah berikut hanya mencakup kelas tindakan huruf besar, tetapi Anda harus mengimplementasikan kedua kelas. Gunakan langkah-langkah untuk menerapkan tindakan huruf besar sebagai pola untuk menerapkan tindakan huruf kecil.
Tambahkan hal berikut menggunakan direktif untuk kelas-kelas ini:
using Microsoft.VisualStudio.Imaging.Interop; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media;
Mendeklarasikan sekumpulan bidang privat.
private ITrackingSpan m_span; private string m_upper; private string m_display; private ITextSnapshot m_snapshot;
Tambahkan konstruktor yang mengatur bidang.
public UpperCaseSuggestedAction(ITrackingSpan span) { m_span = span; m_snapshot = span.TextBuffer.CurrentSnapshot; m_upper = span.GetText(m_snapshot).ToUpper(); m_display = string.Format("Convert '{0}' to upper case", span.GetText(m_snapshot)); }
Terapkan GetPreviewAsync metode sehingga menampilkan pratinjau tindakan.
public Task<object> GetPreviewAsync(CancellationToken cancellationToken) { var textBlock = new TextBlock(); textBlock.Padding = new Thickness(5); textBlock.Inlines.Add(new Run() { Text = m_upper }); return Task.FromResult<object>(textBlock); }
Terapkan GetActionSetsAsync metode sehingga mengembalikan enumerasi kosong SuggestedActionSet .
public Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(CancellationToken cancellationToken) { return Task.FromResult<IEnumerable<SuggestedActionSet>>(null); }
Terapkan properti sebagai berikut.
public bool HasActionSets { get { return false; } } public string DisplayText { get { return m_display; } } public ImageMoniker IconMoniker { get { return default(ImageMoniker); } } public string IconAutomationText { get { return null; } } public string InputGestureText { get { return null; } } public bool HasPreview { get { return true; } }
Terapkan Invoke metode dengan mengganti teks dalam rentang dengan huruf besar yang setara.
public void Invoke(CancellationToken cancellationToken) { m_span.TextBuffer.Replace(m_span.GetSpan(m_snapshot), m_upper); }
Peringatan
Metode Pemanggilan tindakan bola lampu tidak diharapkan untuk menunjukkan UI. Jika tindakan Anda memunculkan UI baru (misalnya dialog pratinjau atau pilihan), jangan tampilkan UI langsung dari dalam metode Panggil tetapi sebaliknya jadwalkan untuk menampilkan UI Anda setelah kembali dari Panggil.
Untuk menyelesaikan implementasi, tambahkan
Dispose()
metode danTryGetTelemetryId()
.public void Dispose() { } public bool TryGetTelemetryId(out Guid telemetryId) { // This is a sample action and doesn't participate in LightBulb telemetry telemetryId = Guid.Empty; return false; }
Jangan lupa untuk melakukan hal yang sama untuk
LowerCaseSuggestedAction
mengubah teks tampilan menjadi "Konversi '{0}' ke huruf kecil" dan panggilan ToUpper ke ToLower.
Membangun dan menguji kode
Untuk menguji kode ini, buat solusi LightBulbTest dan jalankan dalam instans Eksperimental.
Bangun solusinya.
Saat Anda menjalankan proyek ini di debugger, instans kedua Visual Studio dimulai.
Buat file teks dan ketik beberapa teks. Anda akan melihat bola lampu di sebelah kiri teks.
Arahkan ke bola lampu. Anda akan melihat panah bawah.
Saat Anda mengklik bola lampu, dua tindakan yang disarankan harus ditampilkan, bersama dengan pratinjau tindakan yang dipilih.
Jika Anda mengklik tindakan pertama, semua teks dalam kata saat ini harus dikonversi ke huruf besar. Jika Anda mengklik tindakan kedua, semua teks harus dikonversi ke huruf kecil.