Memperluas jendela Properti, Daftar Tugas, Output, dan Opsi
Anda dapat mengakses jendela alat apa pun di Visual Studio. Panduan ini menunjukkan cara mengintegrasikan informasi tentang jendela alat Anda ke halaman Opsi baru dan pengaturan baru di halaman Properti, dan juga cara menulis ke jendela Daftar Tugas dan Output.
Membuat ekstensi dengan jendela alat
Buat proyek bernama TodoList menggunakan templat VSIX, dan tambahkan templat item jendela alat kustom bernama TodoWindow.
Catatan
Untuk informasi selengkapnya tentang membuat ekstensi dengan jendela alat, lihat Membuat ekstensi dengan jendela alat.
Menyiapkan jendela alat
Tambahkan Kotak Teks untuk mengetik item ToDo baru, Tombol untuk menambahkan item baru ke daftar, dan Kotak Daftar untuk menampilkan item dalam daftar.
Di TodoWindow.xaml, hapus kontrol Tombol, Kotak Teks, dan StackPanel dari UserControl.
Catatan
Ini tidak menghapus penanganan aktivitas button1_Click , yang akan Anda gunakan kembali di langkah selanjutnya.
Dari bagian Semua Kontrol WPF dari Kotak Alat, seret kontrol Kanvas ke kisi.
Seret Kotak Teks, Tombol, dan Kotak Daftar ke Kanvas. Susun elemen sehingga Kotak Teks dan Tombol berada pada tingkat yang sama, dan ListBox mengisi sisa jendela di bawahnya, seperti pada gambar di bawah ini.
Di panel XAML, temukan Tombol dan atur properti Kontennya ke Tambahkan. Sambungkan kembali penanganan aktivitas tombol ke kontrol Tombol dengan menambahkan
Click="button1_Click"
atribut. Blok Kanvas akan terlihat seperti ini:<Canvas HorizontalAlignment="Left" Width="306"> <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="208"/> <Button x:Name="button" Content="Add" HorizontalAlignment="Left" Margin="236,13,0,0" VerticalAlignment="Top" Width="48" Click="button1_Click"/> <ListBox x:Name="listBox" HorizontalAlignment="Left" Height="222" Margin="10,56,0,0" VerticalAlignment="Top" Width="274"/> </Canvas>
Menyesuaikan konstruktor
Dalam file TodoWindowControl.xaml.cs, tambahkan yang berikut ini menggunakan direktif:
using System;
Tambahkan referensi publik ke TodoWindow dan minta konstruktor TodoWindowControl mengambil parameter TodoWindow. Kode akan terlihat seperti ini:
public TodoWindow parent; public TodoWindowControl(TodoWindow window) { InitializeComponent(); parent = window; }
Di TodoWindow.cs, ubah konstruktor TodoWindowControl untuk menyertakan parameter TodoWindow. Kode akan terlihat seperti ini:
public TodoWindow() : base(null) { this.Caption = "TodoWindow"; this.BitmapResourceID = 301; this.BitmapIndex = 1; this.Content = new TodoWindowControl(this); }
Membuat halaman Opsi
Anda dapat menyediakan halaman dalam kotak dialog Opsi sehingga pengguna dapat mengubah pengaturan untuk jendela alat. Membuat halaman Opsi memerlukan kelas yang menjelaskan opsi dan entri di file TodoListPackage.cs atau TodoListPackage.vb .
Tambahkan kelas bernama
ToolsOptions.cs
. Buat kelas mewarisiToolsOptions
dari DialogPage.class ToolsOptions : DialogPage { }
Tambahkan yang berikut ini menggunakan direktif:
using Microsoft.VisualStudio.Shell;
Halaman Opsi dalam panduan ini hanya menyediakan satu opsi bernama DaysAhead. Tambahkan bidang privat bernama daysAhead dan properti bernama DaysAhead ke
ToolsOptions
kelas :private double daysAhead; public double DaysAhead { get { return daysAhead; } set { daysAhead = value; } }
Sekarang Anda harus membuat proyek mengetahui halaman Opsi ini.
Membuat halaman Opsi tersedia untuk pengguna
Di TodoWindowPackage.cs, tambahkan ProvideOptionPageAttribute ke
TodoWindowPackage
kelas :[ProvideOptionPage(typeof(ToolsOptions), "ToDo", "General", 101, 106, true)]
Parameter pertama untuk konstruktor ProvideOptionPage adalah jenis kelas
ToolsOptions
, yang Anda buat sebelumnya. Parameter kedua, "ToDo", adalah nama kategori dalam kotak dialog Opsi . Parameter ketiga, "Umum", adalah nama subkataan kotak dialog Opsi tempat halaman Opsi akan tersedia. Dua parameter berikutnya adalah ID sumber daya untuk string; yang pertama adalah nama kategori, dan yang kedua adalah nama subkategori. Parameter akhir menentukan apakah halaman ini dapat diakses dengan menggunakan otomatisasi.Saat pengguna membuka halaman Opsi Anda, halaman tersebut akan menyerupai gambar berikut.
Perhatikan kategori ToDo dan subkategori Umum.
Membuat data tersedia untuk jendela Properti
Anda dapat membuat informasi daftar ToDo tersedia dengan membuat kelas bernama TodoItem
yang menyimpan informasi tentang item individual di daftar ToDo.
Tambahkan kelas bernama
TodoItem.cs
.Ketika jendela alat tersedia untuk pengguna, item di ListBox akan diwakili oleh TodoItems. Saat pengguna memilih salah satu item ini di ListBox, jendela Properti akan menampilkan informasi tentang item tersebut.
Untuk membuat data tersedia di jendela Properti , Anda mengubah data menjadi properti publik yang memiliki dua atribut khusus,
Description
danCategory
.Description
adalah teks yang muncul di bagian bawah jendela Properti .Category
menentukan di mana properti akan muncul ketika jendela Properti ditampilkan dalam tampilan Dikategorikan. Dalam gambar berikut, jendela Properti berada dalam tampilan Dikategorikan, properti Nama di kategori Bidang ToDo dipilih, dan deskripsi properti Nama ditampilkan di bagian bawah jendela.Tambahkan yang berikut ini menggunakan direktif file TodoItem.cs .
using System.ComponentModel; using System.Windows.Forms; using Microsoft.VisualStudio.Shell.Interop;
Tambahkan pengubah
public
akses ke deklarasi kelas.public class TodoItem { }
Tambahkan dua properti,
Name
danDueDate
. Kami akan melakukan danUpdateList()
CheckForErrors()
nanti.public class TodoItem { private TodoWindowControl parent; private string name; [Description("Name of the ToDo item")] [Category("ToDo Fields")] public string Name { get { return name; } set { name = value; parent.UpdateList(this); } } private DateTime dueDate; [Description("Due date of the ToDo item")] [Category("ToDo Fields")] public DateTime DueDate { get { return dueDate; } set { dueDate = value; parent.UpdateList(this); parent.CheckForErrors(); } } }
Tambahkan referensi privat ke kontrol pengguna. Tambahkan konstruktor yang mengambil kontrol pengguna dan nama untuk item ToDo ini. Untuk menemukan nilai untuk
daysAhead
, nilai akan mendapatkan properti halaman Opsi.private TodoWindowControl parent; public TodoItem(TodoWindowControl control, string itemName) { parent = control; name = itemName; dueDate = DateTime.Now; double daysAhead = 0; IVsPackage package = parent.parent.Package as IVsPackage; if (package != null) { object obj; package.GetAutomationObject("ToDo.General", out obj); ToolsOptions options = obj as ToolsOptions; if (options != null) { daysAhead = options.DaysAhead; } } dueDate = dueDate.AddDays(daysAhead); }
Karena instans
TodoItem
kelas akan disimpan di ListBox dan ListBox akan memanggilToString
fungsi, Anda harus membebaniToString
fungsi. Tambahkan kode berikut ke TodoItem.cs, setelah konstruktor dan sebelum akhir kelas.public override string ToString() { return name + " Due: " + dueDate.ToShortDateString(); }
Di TodoWindowControl.xaml.cs, tambahkan metode stub ke
TodoWindowControl
kelas untukCheckForError
metode danUpdateList
. Letakkan setelah ProcessDialogChar dan sebelum akhir file.public void CheckForErrors() { } public void UpdateList(TodoItem item) { }
Metode ini
CheckForError
akan memanggil metode yang memiliki nama yang sama di objek induk, dan metode tersebut akan memeriksa apakah ada kesalahan yang terjadi dan menanganinya dengan benar. MetodeUpdateList
ini akan memperbarui ListBox di kontrol induk; metode dipanggil ketikaName
properti danDueDate
dalam kelas ini berubah. Mereka akan diimplementasikan nanti.
Mengintegrasikan ke dalam jendela Properti
Sekarang tulis kode yang mengelola ListBox, yang akan terikat dengan jendela Properti .
Anda harus mengubah handler klik tombol untuk membaca TextBox, membuat TodoItem, dan menambahkannya ke ListBox.
Ganti fungsi yang
button1_Click
ada dengan kode yang membuat TodoItem baru dan menambahkannya ke ListBox. Ini memanggilTrackSelection()
, yang akan didefinisikan nanti.private void button1_Click(object sender, RoutedEventArgs e) { if (textBox.Text.Length > 0) { var item = new TodoItem(this, textBox.Text); listBox.Items.Add(item); TrackSelection(); CheckForErrors(); } }
Dalam tampilan Desain pilih kontrol ListBox. Di jendela Properti klik tombol Penanganan aktivitas dan temukan peristiwa SelectionChanged . Isi kotak teks dengan listBox_SelectionChanged. Melakukan ini menambahkan stub untuk handler SelectionChanged dan menetapkannya ke peristiwa.
Mengimplementasikan metode
TrackSelection()
. Karena Anda perlu mendapatkan SVsUIShellSTrackSelection layanan, Anda perlu membuat GetService dapat diakses oleh TodoWindowControl. Tambahkan metode berikut ke kelasTodoWindow
:internal object GetVsService(Type service) { return GetService(service); }
Tambahkan yang berikut menggunakan direktif ke TodoWindowControl.xaml.cs:
using System.Runtime.InteropServices; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell;
Isi handler SelectionChanged sebagai berikut:
private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { TrackSelection(); }
Sekarang, isi fungsi TrackSelection, yang akan menyediakan integrasi dengan jendela Properti . Fungsi ini dipanggil ketika pengguna menambahkan item ke ListBox atau mengklik item di ListBox. Ini menambahkan konten ListBox ke SelectionContainer dan meneruskan SelectionContainer ke penanganan aktivitas jendela OnSelectChange Properti. Layanan TrackSelection melacak objek yang dipilih di antarmuka pengguna (UI) dan menampilkan propertinya
private SelectionContainer mySelContainer; private System.Collections.ArrayList mySelItems; private IVsWindowFrame frame = null; private void TrackSelection() { if (frame == null) { var shell = parent.GetVsService(typeof(SVsUIShell)) as IVsUIShell; if (shell != null) { var guidPropertyBrowser = new Guid(ToolWindowGuids.PropertyBrowser); shell.FindToolWindow((uint)__VSFINDTOOLWIN.FTW_fForceCreate, ref guidPropertyBrowser, out frame); } } if (frame != null) { frame.Show(); } if (mySelContainer == null) { mySelContainer = new SelectionContainer(); } mySelItems = new System.Collections.ArrayList(); var selected = listBox.SelectedItem as TodoItem; if (selected != null) { mySelItems.Add(selected); } mySelContainer.SelectedObjects = mySelItems; ITrackSelection track = parent.GetVsService(typeof(STrackSelection)) as ITrackSelection; if (track != null) { track.OnSelectChange(mySelContainer); } }
Sekarang setelah Anda memiliki kelas yang dapat digunakan jendela Properti , Anda dapat mengintegrasikan jendela Properti dengan jendela alat. Ketika pengguna mengklik item di ListBox di jendela alat, jendela Properti harus diperbarui. Demikian pula, ketika pengguna mengubah item ToDo di jendela Properti , item terkait harus diperbarui.
Sekarang, tambahkan kode fungsi UpdateList lainnya di TodoWindowControl.xaml.cs. Ini harus menghilangkan dan menambahkan kembali TodoItem yang dimodifikasi dari ListBox.
public void UpdateList(TodoItem item) { var index = listBox.SelectedIndex; listBox.Items.RemoveAt(index); listBox.Items.Insert(index, item); listBox.SelectedItem = index; }
Uji kode Anda. Bangun proyek dan mulai penelusuran kesalahan. Instans eksperimental akan muncul.
Buka halaman Opsi Alat>. Anda akan melihat kategori ToDo di panel kiri. Kategori tercantum dalam alfabet, jadi lihat di bawah Ts.
Pada halaman Opsi Todo , Anda akan melihat properti diatur
DaysAhead
ke 0. Ubah menjadi 2.Pada menu Lihat/Windows Lainnya, buka TodoWindow. Ketik EndDate di kotak teks dan klik Tambahkan.
Dalam kotak daftar, Anda akan melihat tanggal dua hari lebih lambat dari hari ini.
Menambahkan teks ke jendela Output dan item ke Daftar Tugas
Untuk Daftar Tugas, Anda membuat objek baru bertitik Tugas, lalu menambahkan objek Tugas tersebut ke Daftar Tugas dengan memanggil metodenyaAdd
. Untuk menulis ke jendela Output , Anda memanggil metodenya GetPane
untuk mendapatkan objek panel, lalu Anda memanggil OutputString
metode objek panel.
Di TodoWindowControl.xaml.cs, dalam
button1_Click
metode , tambahkan kode untuk mendapatkan panel Umum jendela Output (yang merupakan default), dan tulis ke dalamnya. Metode ini akan terlihat seperti ini:private void button1_Click(object sender, EventArgs e) { if (textBox.Text.Length > 0) { var item = new TodoItem(this, textBox.Text); listBox.Items.Add(item); var outputWindow = parent.GetVsService( typeof(SVsOutputWindow)) as IVsOutputWindow; IVsOutputWindowPane pane; Guid guidGeneralPane = VSConstants.GUID_OutWindowGeneralPane; outputWindow.GetPane(ref guidGeneralPane, out pane); if (pane != null) { pane.OutputString(string.Format( "To Do item created: {0}\r\n", item.ToString())); } TrackSelection(); CheckForErrors(); } }
Untuk menambahkan item ke Daftar Tugas, Anda perlu menambahkan kelas berlapis ke kelas TodoWindowControl. Kelas berlapis perlu berasal dari TaskProvider. Tambahkan kode berikut ke akhir
TodoWindowControl
kelas.[Guid("72de1eAD-a00c-4f57-bff7-57edb162d0be")] public class TodoWindowTaskProvider : TaskProvider { public TodoWindowTaskProvider(IServiceProvider sp) : base(sp) { } }
Selanjutnya tambahkan referensi privat ke
TodoTaskProvider
danCreateProvider()
metode keTodoWindowControl
kelas . Kode akan terlihat seperti ini:private TodoWindowTaskProvider taskProvider; private void CreateProvider() { if (taskProvider == null) { taskProvider = new TodoWindowTaskProvider(parent); taskProvider.ProviderName = "To Do"; } }
Tambahkan
ClearError()
, yang menghapus Daftar Tugas, danReportError()
, yang menambahkan entri ke Daftar Tugas, keTodoWindowControl
kelas .private void ClearError() { CreateProvider(); taskProvider.Tasks.Clear(); } private void ReportError(string p) { CreateProvider(); var errorTask = new Task(); errorTask.CanDelete = false; errorTask.Category = TaskCategory.Comments; errorTask.Text = p; taskProvider.Tasks.Add(errorTask); taskProvider.Show(); var taskList = parent.GetVsService(typeof(SVsTaskList)) as IVsTaskList2; if (taskList == null) { return; } var guidProvider = typeof(TodoWindowTaskProvider).GUID; taskList.SetActiveProvider(ref guidProvider); }
Sekarang terapkan metode ,
CheckForErrors
sebagai berikut.public void CheckForErrors() { foreach (TodoItem item in listBox.Items) { if (item.DueDate < DateTime.Now) { ReportError("To Do Item is out of date: " + item.ToString()); } } }
Cobalah
Bangun proyek dan mulai penelusuran kesalahan. Instans eksperimental muncul.
Buka TodoWindow (Lihat>Windows>Lain TodoWindow).
Ketik sesuatu dalam kotak teks lalu klik Tambahkan.
Tanggal jatuh tempo 2 hari setelah hari ini ditambahkan ke kotak daftar. Tidak ada kesalahan yang dihasilkan, dan Daftar Tugas (Lihat>Daftar Tugas) seharusnya tidak memiliki entri.
Sekarang ubah pengaturan pada halaman Opsi>Alat>ToDo dari 2 kembali ke 0.
Ketik sesuatu yang lain di TodoWindow lalu klik Tambahkan lagi. Ini memicu kesalahan dan juga entri di Daftar Tugas.
Saat Anda menambahkan item, tanggal awal diatur ke sekarang ditambah 2 hari.
Pada menu Tampilan , klik Output untuk membuka jendela Output .
Perhatikan bahwa setiap kali Anda menambahkan item, pesan ditampilkan di panel Daftar Tugas.
Klik salah satu item di ListBox.
Jendela Properti menampilkan dua properti untuk item tersebut.
Ubah salah satu properti lalu tekan Enter.
Item diperbarui di ListBox.