Rozšíření oken Vlastnosti, Seznam úkolů, Výstup a Možnosti

V sadě Visual Studio máte přístup k libovolnému oknem nástrojů. Tento názorný postup ukazuje, jak integrovat informace o okně nástroje do nové stránky Možnosti a nové nastavení na stránce Vlastnosti a také jak zapisovat do oken Seznam úkolů a Výstup .

Vytvoření rozšíření pomocí okna nástroje

  1. Vytvořte projekt s názvem TodoList pomocí šablony VSIX a přidejte vlastní šablonu okna nástrojů s názvem TodoWindow.

    Poznámka:

    Další informace o vytvoření rozšíření pomocí okna nástroje naleznete v tématu Vytvoření rozšíření s oknem nástroje.

Nastavení okna nástroje

Přidejte TextBox, do kterého chcete zadat novou položku ToDo, tlačítko pro přidání nové položky do seznamu a SeznamBox pro zobrazení položek v seznamu.

  1. V Souboru TodoWindow.xaml odstraňte ovládací prvky Button, TextBox a StackPanel z UserControl.

    Poznámka:

    Tím se neodstraní obslužná rutina události button1_Click , kterou použijete v pozdějším kroku.

  2. V části Všechny ovládací prvky WPF panelu nástrojů přetáhněte ovládací prvek Plátno do mřížky.

  3. Přetáhněte TextBox, tlačítko a ListBox na plátno. Uspořádejte prvky tak, aby textové pole a tlačítko byly na stejné úrovni a ListBox vyplní zbytek okna pod nimi, jak je znázorněno na obrázku níže.

    Finished Tool Window

  4. V podokně XAML vyhledejte tlačítko a nastavte jeho vlastnost Content na Přidat. Znovu připojte obslužnou rutinu události tlačítka k ovládacímu prvku Button přidáním atributu Click="button1_Click" . Blok plátna by měl vypadat takto:

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

Přizpůsobení konstruktoru

  1. Do souboru TodoWindowControl.xaml.cs přidejte následující direktivu using:

    using System;
    
  2. Přidejte veřejný odkaz na TodoWindow a mít TodoWindowControl konstruktor vzít TodoWindow parametr. Kód by měl vypadat takto:

    public TodoWindow parent;
    
    public TodoWindowControl(TodoWindow window)
    {
        InitializeComponent();
        parent = window;
    }
    
  3. V TodoWindow.cs změňte TodoWindowControl konstruktor tak, aby zahrnoval TodoWindow parametr. Kód by měl vypadat takto:

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

Vytvoření stránky Možnosti

Stránku můžete zadat v dialogovém okně Možnosti , aby uživatelé mohli změnit nastavení pro okno nástroje. Vytvoření stránky Options vyžaduje třídu, která popisuje možnosti a položku v souboru TodoListPackage.cs nebo TodoListPackage.vb .

  1. Přidejte třídu s názvem ToolsOptions.cs. ToolsOptions Nastavení třídy zdědí z DialogPage.

    class ToolsOptions : DialogPage
    {
    }
    
  2. Přidejte následující direktivu using:

    using Microsoft.VisualStudio.Shell;
    
  3. Stránka Možnosti v tomto názorném postupu poskytuje pouze jednu možnost s názvem DaysAhead. Přidejte do třídy soukromé pole s názvem daysAhead a vlastnost s názvem DaysAheadToolsOptions:

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

    Nyní musíte projekt upozornit na tuto stránku Možnosti.

Zpřístupnění stránky Možnosti uživatelům

  1. V TodoWindowPackage.cs přidejte ProvideOptionPageAttribute do TodoWindowPackage třídy:

    [ProvideOptionPage(typeof(ToolsOptions), "ToDo", "General", 101, 106, true)]
    
  2. První parametr konstruktoru ProvideOptionPage je typ třídy ToolsOptions, kterou jste vytvořili dříve. Druhý parametr ToDo je název kategorie v dialogovém okně Možnosti . Třetí parametr " Obecné" je název podkategorie dialogového okna Možnosti , kde bude stránka Možnosti k dispozici. Další dva parametry jsou ID prostředků pro řetězce; první je název kategorie a druhý je název podkategorie. Poslední parametr určuje, zda je tato stránka přístupná pomocí automatizace.

    Když uživatel otevře stránku Možnosti, měla by vypadat podobně jako na následujícím obrázku.

    Options Page

    Všimněte si kategorie ToDo a podkategorie Obecné.

Zpřístupnění dat pro okno Vlastnosti

Informace o seznamu úkolů můžete zpřístupnit vytvořením třídy s názvem TodoItem , která ukládá informace o jednotlivých položkách v seznamu úkolů.

  1. Přidejte třídu s názvem TodoItem.cs.

    Pokud je okno nástroje k dispozici uživatelům, budou položky v SeznamuBox reprezentovány todoItems. Když uživatel vybere jednu z těchto položek v SeznamuBox, okno Vlastnosti zobrazí informace o položce.

    Pokud chcete data zpřístupnit v okně Vlastnosti , změníte data na veřejné vlastnosti, které mají dva speciální atributy a Description Category. Description je text, který se zobrazí v dolní části okna Vlastnosti . Categoryurčuje, kde by se vlastnost měla zobrazit, když se okno Vlastnosti zobrazí v zobrazení zařazené do kategorií. Na následujícím obrázku je okno Vlastnosti v zobrazení Zařazeno do kategorií, je vybrána vlastnost Name v kategorii Pole úkolů a popis vlastnosti Název se zobrazí v dolní části okna.

    Properties Window

  2. Přidejte následující direktivy using souboru TodoItem.cs .

    using System.ComponentModel;
    using System.Windows.Forms;
    using Microsoft.VisualStudio.Shell.Interop;
    
  3. public Přidejte modifikátor přístupu do deklarace třídy.

    public class TodoItem
    {
    }
    

    Přidejte dvě vlastnosti Name a DueDate. Uděláme to UpdateList() a CheckForErrors() později.

    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. Přidejte do uživatelského ovládacího prvku soukromý odkaz. Přidejte konstruktor, který převezme uživatelský ovládací prvek a název této položky ToDo. Chcete-li najít hodnotu pro daysAhead, získá vlastnost Možnosti stránky.

    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. Protože instance třídy budou uloženy TodoItem v ListBox a ListBox bude volat ToString funkci, musíte přetížit ToString funkci. Do souboru TodoItem.cs přidejte následující kód za konstruktor a před konec třídy.

    public override string ToString()
    {
        return name + " Due: " + dueDate.ToShortDateString();
    }
    
  6. V TodoWindowControl.xaml.cs přidejte metody zástupných procedur do TodoWindowControl třídy pro metody CheckForError a UpdateList metody. Umístěte je za ProcessDialogChar a před konec souboru.

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

    Metoda CheckForError zavolá metodu se stejným názvem v nadřazeného objektu a tato metoda zkontroluje, jestli nedošlo k nějakým chybám, a zpracuje je správně. Metoda UpdateList aktualizuje ListBox v nadřazené ovládací prvek; metoda je volána při Name změně a DueDate vlastnosti v této třídě. Budou implementovány později.

Integrace do okno Vlastnosti

Teď napište kód, který spravuje ListBox, který bude svázán s oknem Vlastnosti .

Je nutné změnit obslužnou rutinu kliknutí na tlačítko pro čtení TextBox, vytvořit TodoItem a přidat ho do ListBox.

  1. Nahraďte existující button1_Click funkci kódem, který vytvoří nový TodoItem a přidá ji do ListBoxu. TrackSelection()Zavolá , která bude definována později.

    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. V návrhovém zobrazení vyberte ovládací prvek ListBox. V okně Vlastnosti klikněte na tlačítko Obslužné rutiny událostí a vyhledejte událost SelectionChanged . Do textového pole zadejte listBox_SelectionChanged. Tímto způsobem přidáte zástupný proceduru pro obslužnou rutinu SelectionChanged a přiřadí ji k události.

  3. Implementujte metodu TrackSelection() . Vzhledem k tomu, že budete potřebovat získat SVsUIShellSTrackSelection služby, musíte zpřístupnit GetService TodoWindowControl. Do třídy TodoWindow přidejte následující metodu:

    internal object GetVsService(Type service)
    {
        return GetService(service);
    }
    
  4. Do souboru TodoWindowControl.xaml.cs přidejte následující direktivy using:

    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Shell;
    
  5. Obslužnou rutinu SelectionChanged vyplňte následujícím způsobem:

    private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        TrackSelection();
    }
    
  6. Teď vyplňte funkci TrackSelection, která zajistí integraci s oknem Vlastnosti . Tato funkce je volána, když uživatel přidá položku do ListBox nebo klikne na položku v ListBox. Přidá obsah ListBox do SelectionContainer a předá SelectionContainer obslužné rutině události okna OnSelectChange Vlastnosti. Služba TrackSelection sleduje vybrané objekty v uživatelském rozhraní a zobrazuje jejich vlastnosti.

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

    Teď, když máte třídu, kterou může okno Vlastnosti použít, můžete integrovat okno Vlastnosti s oknem nástroje. Když uživatel klikne na položku v seznamu v okně nástroje, mělo by se okno Vlastnosti odpovídajícím způsobem aktualizovat. Podobně platí, že když uživatel změní položku ToDo v okně Vlastnosti , přidružená položka by měla být aktualizována.

  7. Nyní přidejte zbytek kódu funkce UpdateList v TodoWindowControl.xaml.cs. Měl by vypustit a znovu přidat upravený TodoItem ze seznamu.

    public void UpdateList(TodoItem item)
    {
        var index = listBox.SelectedIndex;
        listBox.Items.RemoveAt(index);
        listBox.Items.Insert(index, item);
        listBox.SelectedItem = index;
    }
    
  8. Otestujte kód. Sestavte projekt a spusťte ladění. Měla by se zobrazit experimentální instance.

  9. Otevřete stránku Možnosti nástrojů>. V levém podokně by se měla zobrazit kategorie ToDo. Kategorie jsou uvedené v abecedním pořadí, takže se podívejte pod Ts.

  10. Na stránce Možností todo by se měla zobrazit vlastnost nastavená DaysAhead na 0. Změňte ho na 2.

  11. V nabídce View / Other Windows otevřete TodoWindow. Do textového pole zadejte EndDate a klikněte na Přidat.

  12. V seznamu byste měli vidět datum o dva dny později než dnes.

Přidání textu do okna Výstup a položek do seznamu úkolů

Pro seznam úkolů vytvoříte nový objekt typu Úkol a pak tento objekt Task přidáte do seznamu úkolů voláním jeho Add metody. Chcete-li zapisovat do okna Výstup , zavoláte jeho GetPane metodu pro získání objektu podokna a pak zavoláte OutputString metodu objektu podokna.

  1. V TodoWindowControl.xaml.cs v button1_Click metodě přidejte kód, který získá obecné podokno výstupního okna (což je výchozí) a zapište do něj. Metoda by měla vypadat takto:

    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. Chcete-li přidat položky do seznamu úkolů, musíte přidat vnořenou třídu do todoWindowControl třídy. Vnořená třída musí být odvozena od TaskProvider. Na konec TodoWindowControl třídy přidejte následující kód.

    [Guid("72de1eAD-a00c-4f57-bff7-57edb162d0be")]
    public class TodoWindowTaskProvider : TaskProvider
    {
        public TodoWindowTaskProvider(IServiceProvider sp)
            : base(sp)
        {
        }
    }
    
  3. Dále do třídy přidejte soukromý odkaz TodoTaskProvider a metodu CreateProvider() TodoWindowControl . Kód by měl vypadat takto:

    private TodoWindowTaskProvider taskProvider;
    private void CreateProvider()
    {
        if (taskProvider == null)
        {
            taskProvider = new TodoWindowTaskProvider(parent);
            taskProvider.ProviderName = "To Do";
        }
    }
    
  4. Přidejte ClearError(), který vymaže seznam úkolů a ReportError(), který přidá položku do seznamu úkolů, do TodoWindowControl třídy.

    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. Nyní implementujte metodu CheckForErrors následujícím způsobem.

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

Vyzkoušejte si to.

  1. Sestavte projekt a spusťte ladění. Zobrazí se experimentální instance.

  2. Otevřete todoWindow (zobrazit>ostatní windows>TodoWindow).

  3. Do textového pole zadejte něco a klikněte na Přidat.

    Termín splnění 2 dny po dnešním přidání do seznamu. Nejsou generovány žádné chyby a seznam úkolů (zobrazit>seznam úkolů) by neměl obsahovat žádné položky.

  4. Teď změňte nastavení na stránce Možnosti úkolů> nástroje>z 2 zpět na 0.

  5. Do pole TodoWindow zadejte něco jiného a klikněte znovu na tlačítko Přidat. Tím se aktivuje chyba a také položka v seznamu úkolů.

    Při přidávání položek je počáteční datum nastavené na 2 dny.

  6. V nabídce Zobrazit kliknutím na Výstup otevřete okno Výstup.

    Všimněte si, že při každém přidání položky se v podokně Seznam úloh zobrazí zpráva.

  7. Klikněte na jednu z položek v seznamu.

    V okně Vlastnosti se zobrazí dvě vlastnosti položky.

  8. Změňte jednu z vlastností a stiskněte Enter.

    Položka se aktualizuje v listboxu.