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
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.
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.
W sekcji Wszystkie kontrolki WPF przybornika przeciągnij kontrolkę Kanwa do siatki.
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.
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
W pliku TodoWindowControl.xaml.cs dodaj następującą dyrektywę using:
using System;
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; }
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 .
Dodaj klasę o nazwie
ToolsOptions.cs
. Ustaw klasę na dziedziczenieToolsOptions
z klasy DialogPage.class ToolsOptions : DialogPage { }
Dodaj następującą dyrektywę using:
using Microsoft.VisualStudio.Shell;
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
W pliku TodoWindowPackage.cs dodaj element ProvideOptionPageAttribute do
TodoWindowPackage
klasy:[ProvideOptionPage(typeof(ToolsOptions), "ToDo", "General", 101, 106, true)]
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.
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.
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
Description
Category
.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.Dodaj następujące dyrektywy using do pliku TodoItem.cs .
using System.ComponentModel; using System.Windows.Forms; using Microsoft.VisualStudio.Shell.Interop;
public
Dodaj modyfikator dostępu do deklaracji klasy.public class TodoItem { }
Dodaj dwie właściwości i
Name
DueDate
. Zrobimy toUpdateList()
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(); } } }
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); }
Ponieważ wystąpienia
TodoItem
klasy będą przechowywane w ListBox, a pole ListBox wywołaToString
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(); }
W pliku TodoWindowControl.xaml.cs dodaj metody wycinkowe do
TodoWindowControl
klasy dlaCheckForError
metod iUpdateList
. 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. MetodaUpdateList
zaktualizuje pole ListBox w kontrolce nadrzędnej; metoda jest wywoływana, gdyName
właściwości iDueDate
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.
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(); } }
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.
Zaimplementuj metodę
TrackSelection()
. Ponieważ musisz uzyskać SVsUIShellSTrackSelection usługi, musisz udostępnić GetService go za pomocą funkcji TodoWindowControl. Dodaj następującą metodę do klasyTodoWindow
:internal object GetVsService(Type service) { return GetService(service); }
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;
Wypełnij procedurę obsługi SelectionChanged w następujący sposób:
private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { TrackSelection(); }
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.
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; }
Przetestuj kod. Skompiluj projekt i rozpocznij debugowanie. Powinno zostać wyświetlone wystąpienie eksperymentalne.
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.
Na stronie Opcje do wykonania powinna zostać wyświetlona właściwość ustawiona
DaysAhead
na 0. Zmień ją na 2.W menu Widok/Inne okna otwórz pozycję TodoWindow. Wpisz EndDate w polu tekstowym i kliknij przycisk Dodaj.
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.
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(); } }
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) { } }
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"; } }
Dodaj
ClearError()
element , który czyści listę zadań iReportError()
, który dodaje wpis do listy zadań doTodoWindowControl
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); }
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ć
Skompiluj projekt i rozpocznij debugowanie. Zostanie wyświetlone wystąpienie eksperymentalne.
Otwórz okno TodoWindow (Wyświetl>inne okna zadań do wykonania w systemie Windows).>
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.
Teraz zmień ustawienie na stronie Opcje narzędzi>>Do wykonania z 2 z powrotem do 0.
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.
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.
Kliknij jeden z elementów w polu ListBox.
W oknie Właściwości zostaną wyświetlone dwie właściwości elementu.
Zmień jedną z właściwości, a następnie naciśnij klawisz Enter.
Element jest aktualizowany w polu ListBox.