Udostępnij za pośrednictwem


Rozszerzanie okien właściwości, listy zadań, danych wyjściowych i opcji

Dostęp do dowolnego okna narzędzi można uzyskać w programie Visual Studio. W tym przewodniku pokazano, jak zintegrować informacje o oknie narzędzia z nową stroną Opcje i nowym ustawieniem na stronie Właściwości, a także jak zapisywać informacje w oknach Lista zadań i Dane wyjściowe.

Tworzenie rozszerzenia za pomocą okna narzędzi

  1. Utwórz projekt o nazwie TodoList przy użyciu szablonu VSIX i dodaj niestandardowy szablon elementu okna narzędzia o nazwie TodoWindow.

    Uwaga

    Aby uzyskać więcej informacji na temat tworzenia rozszerzenia za pomocą okna narzędzi, zobacz Tworzenie rozszerzenia za pomocą okna narzędzi.

Konfigurowanie okna narzędzi

Dodaj pole tekstowe, w którym wpisz nowy element ToDo, przycisk, aby dodać nowy element do listy, oraz pole ListBox, aby wyświetlić elementy na liście.

  1. W pliku TodoWindow.xaml usuń kontrolki Button, TextBox i StackPanel z kontrolki UserControl.

    Uwaga

    Nie powoduje to usunięcia programu obsługi zdarzeń button1_Click , który zostanie użyty ponownie w późniejszym kroku.

  2. W sekcji Wszystkie kontrolki WPF przybornika przeciągnij kontrolkę Kanwa do siatki.

  3. Przeciągnij pole tekstowe, przycisk i pole ListBox do kanwy. Rozmieść elementy tak, aby pole TextBox i przycisk były na tym samym poziomie, a pole ListBox wypełnia resztę okna poniżej, jak na poniższej ilustracji.

    Finished Tool Window

  4. W okienku XAML znajdź przycisk i ustaw jego właściwość Content na Dodaj. Ponownie połącz procedurę obsługi zdarzeń przycisku z kontrolką Przycisk, dodając Click="button1_Click" atrybut. Blok Kanwy powinien wyglądać następująco:

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

Dostosowywanie konstruktora

  1. W pliku TodoWindowControl.xaml.cs dodaj następującą dyrektywę using:

    using System;
    
  2. Dodaj publiczne odwołanie do elementu TodoWindow i konstruktor TodoWindowControl przyjmuje parametr TodoWindowControl. Kod powinien wyglądać następująco:

    public TodoWindow parent;
    
    public TodoWindowControl(TodoWindow window)
    {
        InitializeComponent();
        parent = window;
    }
    
  3. W pliku TodoWindow.cs zmień konstruktor TodoWindowControl, aby uwzględnić parametr TodoWindow. Kod powinien wyglądać następująco:

    public TodoWindow() : base(null)
    {
        this.Caption = "TodoWindow";
        this.BitmapResourceID = 301;
        this.BitmapIndex = 1;
    
         this.Content = new TodoWindowControl(this);
    }
    

Tworzenie strony Opcje

Stronę można podać w oknie dialogowym Opcje , aby użytkownicy mogli zmieniać ustawienia okna narzędzi. Utworzenie strony Opcje wymaga zarówno klasy, która opisuje opcje, jak i wpis w pliku TodoListPackage.cs lub TodoListPackage.vb .

  1. Dodaj klasę o nazwie ToolsOptions.cs. Ustaw klasę na dziedziczenie ToolsOptions z klasy DialogPage.

    class ToolsOptions : DialogPage
    {
    }
    
  2. Dodaj następującą dyrektywę using:

    using Microsoft.VisualStudio.Shell;
    
  3. Strona Opcje w tym przewodniku zawiera tylko jedną opcję o nazwie DaysAhead. Dodaj pole prywatne o nazwie daysAhead i właściwość o nazwie DaysAhead do ToolsOptions klasy:

    private double daysAhead;
    
    public double DaysAhead
    {
        get { return daysAhead; }
        set { daysAhead = value; }
    }
    

    Teraz musisz poinformować projekt o tej stronie Opcje.

Udostępnianie użytkownikom strony Opcje

  1. W pliku TodoWindowPackage.cs dodaj element ProvideOptionPageAttribute do TodoWindowPackage klasy:

    [ProvideOptionPage(typeof(ToolsOptions), "ToDo", "General", 101, 106, true)]
    
  2. Pierwszym parametrem konstruktora ProvideOptionPage jest typ klasy ToolsOptions, która została utworzona wcześniej. Drugi parametr "ToDo" to nazwa kategorii w oknie dialogowym Opcje . Trzeci parametr "Ogólne" to nazwa podkategorii okna dialogowego Opcje, na której będzie dostępna strona Opcje . Dwa następne parametry to identyfikatory zasobów dla ciągów; pierwszy to nazwa kategorii, a druga to nazwa podkategorii. Końcowy parametr określa, czy ta strona może być dostępna przy użyciu automatyzacji.

    Gdy użytkownik otworzy stronę Opcje, powinien wyglądać podobnie jak na poniższej ilustracji.

    Options Page

    Zwróć uwagę na kategorię ToDo i podkategorię Ogólne.

Udostępnianie danych okno Właściwości

Możesz udostępnić informacje o liście zadań do wykonania, tworząc klasę o nazwie TodoItem , która przechowuje informacje o poszczególnych elementach na liście Zadań do wykonania.

  1. Dodaj klasę o nazwie TodoItem.cs.

    Gdy okno narzędzia jest dostępne dla użytkowników, elementy w polu Listy będą reprezentowane przez todoItems. Gdy użytkownik wybierze jeden z tych elementów w Polu listy, w oknie Właściwości zostaną wyświetlone informacje o elemencie.

    Aby udostępnić dane w oknie Właściwości, należy przekształcić dane w właściwości publiczne, które mają dwa atrybuty specjalne i DescriptionCategory. Description to tekst wyświetlany w dolnej części okna Właściwości . Category określa, gdzie właściwość powinna być wyświetlana po wyświetleniu okna Właściwości w widoku Kategorii . Na poniższej ilustracji okno Właściwości znajduje się w widoku Podzielone na kategorie, właściwość Name w kategorii Pola zadań do wykonania jest zaznaczona, a opis właściwości Name jest wyświetlany w dolnej części okna.

    Properties Window

  2. Dodaj następujące dyrektywy using do pliku TodoItem.cs .

    using System.ComponentModel;
    using System.Windows.Forms;
    using Microsoft.VisualStudio.Shell.Interop;
    
  3. public Dodaj modyfikator dostępu do deklaracji klasy.

    public class TodoItem
    {
    }
    

    Dodaj dwie właściwości i NameDueDate. Zrobimy to UpdateList()CheckForErrors() później.

    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. Dodaj prywatne odwołanie do kontrolki użytkownika. Dodaj konstruktor, który przyjmuje kontrolkę użytkownika i nazwę tego elementu ToDo. Aby znaleźć wartość parametru daysAhead, pobiera właściwość strony Opcje.

    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. Ponieważ wystąpienia TodoItem klasy będą przechowywane w ListBox, a pole ListBox wywoła ToString funkcję, należy przeciążyć ToString funkcję. Dodaj następujący kod do pliku TodoItem.cs po konstruktorze i przed końcem klasy.

    public override string ToString()
    {
        return name + " Due: " + dueDate.ToShortDateString();
    }
    
  6. W pliku TodoWindowControl.xaml.cs dodaj metody wycinkowe do TodoWindowControl klasy dla CheckForError metod i UpdateList . Umieść je po pliku ProcessDialogChar i przed końcem pliku.

    public void CheckForErrors()
    {
    }
    public void UpdateList(TodoItem item)
    {
    }
    

    Metoda CheckForError wywoła metodę, która ma taką samą nazwę w obiekcie nadrzędnym, a metoda sprawdzi, czy wystąpiły jakiekolwiek błędy i prawidłowo je obsłuży. Metoda UpdateList zaktualizuje pole ListBox w kontrolce nadrzędnej; metoda jest wywoływana, gdy Name właściwości i DueDate w tej klasie się zmieniają. Zostaną one zaimplementowane później.

Integracja z okno Właściwości

Teraz napisz kod, który zarządza polem ListBox, który zostanie powiązany z oknem Właściwości .

Należy zmienić procedurę obsługi kliknięć przycisku, aby odczytać pole tekstowe, utworzyć obiekt TodoItem i go do kontrolki ListBox.

  1. Zastąp istniejącą button1_Click funkcję kodem, który tworzy nowy element TodoItem i dodaje go do kontrolki ListBox. Wywołuje metodę TrackSelection(), która zostanie zdefiniowana później.

    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. W widoku Projekt wybierz kontrolkę ListBox. W oknie Właściwości kliknij przycisk Programy obsługi zdarzeń i znajdź zdarzenie SelectionChanged. Wypełnij pole tekstowe listBox_SelectionChanged. Spowoduje to dodanie wycinku programu obsługi SelectionChanged i przypisanie go do zdarzenia.

  3. Zaimplementuj metodę TrackSelection() . Ponieważ musisz uzyskać SVsUIShellSTrackSelection usługi, musisz udostępnić GetService go za pomocą funkcji TodoWindowControl. Dodaj następującą metodę do klasy TodoWindow:

    internal object GetVsService(Type service)
    {
        return GetService(service);
    }
    
  4. Dodaj następujące dyrektywy using do pliku TodoWindowControl.xaml.cs:

    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Shell;
    
  5. Wypełnij procedurę obsługi SelectionChanged w następujący sposób:

    private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        TrackSelection();
    }
    
  6. Teraz wypełnij funkcję TrackSelection, która zapewni integrację z oknem Właściwości . Ta funkcja jest wywoływana, gdy użytkownik dodaje element do kontrolki ListBox lub klika element w polu ListBox. Dodaje zawartość kontrolki ListBox do obiektu SelectionContainer i przekazuje element SelectionContainer do programu obsługi zdarzeń okna OnSelectChange Właściwości. Usługa TrackSelection śledzi wybrane obiekty w interfejsie użytkownika i wyświetla ich właściwości

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

    Teraz, gdy masz klasę, której można użyć w oknie Właściwości , możesz zintegrować okno Właściwości z oknem narzędzia. Gdy użytkownik kliknie element w polu ListBox w oknie narzędzia, należy odpowiednio zaktualizować okno Właściwości . Podobnie, gdy użytkownik zmieni element ToDo w oknie Właściwości , skojarzony element powinien zostać zaktualizowany.

  7. Teraz dodaj pozostałą część kodu funkcji UpdateList w pliku TodoWindowControl.xaml.cs. Powinien on zostać porzucony i ponownie dodać zmodyfikowany element TodoItem z listy ListBox.

    public void UpdateList(TodoItem item)
    {
        var index = listBox.SelectedIndex;
        listBox.Items.RemoveAt(index);
        listBox.Items.Insert(index, item);
        listBox.SelectedItem = index;
    }
    
  8. Przetestuj kod. Skompiluj projekt i rozpocznij debugowanie. Powinno zostać wyświetlone wystąpienie eksperymentalne.

  9. Otwórz stronę Opcje narzędzi>. W okienku po lewej stronie powinna zostać wyświetlona kategoria ToDo. Kategorie są wymienione w kolejności alfabetycznej, więc zapoznaj się z Ts.

  10. Na stronie Opcje do wykonania powinna zostać wyświetlona właściwość ustawiona DaysAhead na 0. Zmień ją na 2.

  11. W menu Widok/Inne okna otwórz pozycję TodoWindow. Wpisz EndDate w polu tekstowym i kliknij przycisk Dodaj.

  12. W polu listy powinna zostać wyświetlona data dwa dni później niż dzisiaj.

Dodawanie tekstu do okna Dane wyjściowe i elementy do listy zadań

W przypadku listy zadań utworzysz nowy obiekt typu Task, a następnie dodaj ten obiekt Task do listy zadań, wywołując jego Add metodę. Aby zapisać w oknie Dane wyjściowe , należy wywołać jego GetPane metodę w celu uzyskania obiektu okienka, a następnie wywołać OutputString metodę obiektu okienka.

  1. W pliku TodoWindowControl.xaml.cs w metodzie button1_Click dodaj kod, aby uzyskać okienko Ogólne w oknie Dane wyjściowe (które jest wartością domyślną) i zapisz go w nim. Metoda powinna teraz wyglądać następująco:

    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. Aby dodać elementy do listy zadań, należy dodać klasę zagnieżdżoną do klasy TodoWindowControl. Zagnieżdżona klasa musi pochodzić z klasy TaskProvider. Dodaj następujący kod na końcu TodoWindowControl klasy.

    [Guid("72de1eAD-a00c-4f57-bff7-57edb162d0be")]
    public class TodoWindowTaskProvider : TaskProvider
    {
        public TodoWindowTaskProvider(IServiceProvider sp)
            : base(sp)
        {
        }
    }
    
  3. Następnie dodaj prywatne odwołanie do TodoTaskProvider klasy i metodę CreateProvider()TodoWindowControl . Kod powinien wyglądać następująco:

    private TodoWindowTaskProvider taskProvider;
    private void CreateProvider()
    {
        if (taskProvider == null)
        {
            taskProvider = new TodoWindowTaskProvider(parent);
            taskProvider.ProviderName = "To Do";
        }
    }
    
  4. Dodaj ClearError()element , który czyści listę zadań i ReportError(), który dodaje wpis do listy zadań do TodoWindowControl klasy .

    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. Teraz zaimplementuj metodę CheckForErrors w następujący sposób.

    public void CheckForErrors()
    {
        foreach (TodoItem item in listBox.Items)
        {
            if (item.DueDate < DateTime.Now)
            {
                ReportError("To Do Item is out of date: "
                    + item.ToString());
            }
        }
    }
    

Czas to wypróbować

  1. Skompiluj projekt i rozpocznij debugowanie. Zostanie wyświetlone wystąpienie eksperymentalne.

  2. Otwórz okno TodoWindow (Wyświetl>inne okna zadań do wykonania w systemie Windows).>

  3. Wpisz coś w polu tekstowym, a następnie kliknij przycisk Dodaj.

    Data ukończenia 2 dni po dodaniu dnia dzisiejszego do pola listy. Nie są generowane żadne błędy, a lista zadań (wyświetl>listę zadań) nie powinna zawierać żadnych wpisów.

  4. Teraz zmień ustawienie na stronie Opcje narzędzi>>Do wykonania z 2 z powrotem do 0.

  5. Wpisz coś innego w polu TodoWindow , a następnie kliknij przycisk Dodaj ponownie. Spowoduje to wyzwolenie błędu, a także wpisu na liście zadań.

    Podczas dodawania elementów początkowa data jest ustawiona na teraz plus 2 dni.

  6. W menu Widok kliknij pozycję Dane wyjściowe, aby otworzyć okno Dane wyjściowe.

    Zwróć uwagę, że za każdym razem, gdy dodasz element, w okienku Lista zadań jest wyświetlany komunikat.

  7. Kliknij jeden z elementów w polu ListBox.

    W oknie Właściwości zostaną wyświetlone dwie właściwości elementu.

  8. Zmień jedną z właściwości, a następnie naciśnij klawisz Enter.

    Element jest aktualizowany w polu ListBox.