Bagikan melalui


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

  1. 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.

  1. 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.

  2. Dari bagian Semua Kontrol WPF dari Kotak Alat, seret kontrol Kanvas ke kisi.

  3. 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.

    Finished Tool Window

  4. 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

  1. Dalam file TodoWindowControl.xaml.cs, tambahkan yang berikut ini menggunakan direktif:

    using System;
    
  2. 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;
    }
    
  3. 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 .

  1. Tambahkan kelas bernama ToolsOptions.cs. Buat kelas mewarisi ToolsOptions dari DialogPage.

    class ToolsOptions : DialogPage
    {
    }
    
  2. Tambahkan yang berikut ini menggunakan direktif:

    using Microsoft.VisualStudio.Shell;
    
  3. 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

  1. Di TodoWindowPackage.cs, tambahkan ProvideOptionPageAttribute ke TodoWindowPackage kelas :

    [ProvideOptionPage(typeof(ToolsOptions), "ToDo", "General", 101, 106, true)]
    
  2. 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.

    Options Page

    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.

  1. 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 dan Category. Description adalah teks yang muncul di bagian bawah jendela Properti . Categorymenentukan 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.

    Properties Window

  2. Tambahkan yang berikut ini menggunakan direktif file TodoItem.cs .

    using System.ComponentModel;
    using System.Windows.Forms;
    using Microsoft.VisualStudio.Shell.Interop;
    
  3. Tambahkan pengubah public akses ke deklarasi kelas.

    public class TodoItem
    {
    }
    

    Tambahkan dua properti, Name dan DueDate. Kami akan melakukan dan UpdateList() 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();
            }
        }
    }
    
  4. 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);
    }
    
  5. Karena instans TodoItem kelas akan disimpan di ListBox dan ListBox akan memanggil ToString fungsi, Anda harus membebani ToString fungsi. Tambahkan kode berikut ke TodoItem.cs, setelah konstruktor dan sebelum akhir kelas.

    public override string ToString()
    {
        return name + " Due: " + dueDate.ToShortDateString();
    }
    
  6. Di TodoWindowControl.xaml.cs, tambahkan metode stub ke TodoWindowControl kelas untuk CheckForError metode dan UpdateList . 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. Metode UpdateList ini akan memperbarui ListBox di kontrol induk; metode dipanggil ketika Name properti dan DueDate 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.

  1. Ganti fungsi yang button1_Click ada dengan kode yang membuat TodoItem baru dan menambahkannya ke ListBox. Ini memanggil TrackSelection(), 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();
        }
    }
    
  2. 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.

  3. Mengimplementasikan metode TrackSelection(). Karena Anda perlu mendapatkan SVsUIShellSTrackSelection layanan, Anda perlu membuat GetService dapat diakses oleh TodoWindowControl. Tambahkan metode berikut ke kelas TodoWindow:

    internal object GetVsService(Type service)
    {
        return GetService(service);
    }
    
  4. 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;
    
  5. Isi handler SelectionChanged sebagai berikut:

    private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        TrackSelection();
    }
    
  6. 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.

  7. 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;
    }
    
  8. Uji kode Anda. Bangun proyek dan mulai penelusuran kesalahan. Instans eksperimental akan muncul.

  9. Buka halaman Opsi Alat>. Anda akan melihat kategori ToDo di panel kiri. Kategori tercantum dalam alfabet, jadi lihat di bawah Ts.

  10. Pada halaman Opsi Todo , Anda akan melihat properti diatur DaysAhead ke 0. Ubah menjadi 2.

  11. Pada menu Lihat/Windows Lainnya, buka TodoWindow. Ketik EndDate di kotak teks dan klik Tambahkan.

  12. 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.

  1. 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();
        }
    }
    
  2. 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)
        {
        }
    }
    
  3. Selanjutnya tambahkan referensi privat ke TodoTaskProvider dan CreateProvider() metode ke TodoWindowControl kelas . Kode akan terlihat seperti ini:

    private TodoWindowTaskProvider taskProvider;
    private void CreateProvider()
    {
        if (taskProvider == null)
        {
            taskProvider = new TodoWindowTaskProvider(parent);
            taskProvider.ProviderName = "To Do";
        }
    }
    
  4. Tambahkan ClearError(), yang menghapus Daftar Tugas, dan ReportError(), yang menambahkan entri ke Daftar Tugas, ke TodoWindowControl 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);
    }
    
  5. 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

  1. Bangun proyek dan mulai penelusuran kesalahan. Instans eksperimental muncul.

  2. Buka TodoWindow (Lihat>Windows>Lain TodoWindow).

  3. 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.

  4. Sekarang ubah pengaturan pada halaman Opsi>Alat>ToDo dari 2 kembali ke 0.

  5. 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.

  6. Pada menu Tampilan , klik Output untuk membuka jendela Output .

    Perhatikan bahwa setiap kali Anda menambahkan item, pesan ditampilkan di panel Daftar Tugas.

  7. Klik salah satu item di ListBox.

    Jendela Properti menampilkan dua properti untuk item tersebut.

  8. Ubah salah satu properti lalu tekan Enter.

    Item diperbarui di ListBox.