Étendre les fenêtres Propriétés, Liste des tâches, Sortie et Options

Vous pouvez accéder à n’importe quelle fenêtre d’outil dans Visual Studio. Cette procédure pas à pas montre comment intégrer des informations sur votre fenêtre d’outil dans une nouvelle page Options et un nouveau paramètre sur la page Propriétés , et comment écrire dans les fenêtres Liste des tâches et Sortie .

Créer une extension avec une fenêtre d’outil

  1. Créez un projet nommé TodoList à l’aide du modèle VSIX et ajoutez un modèle d’élément de fenêtre d’outil personnalisé nommé TodoWindow.

    Remarque

    Pour plus d’informations sur la création d’une extension avec une fenêtre d’outil, consultez Créer une extension avec une fenêtre d’outil.

Configurer la fenêtre outil

Ajoutez une zone de texte dans laquelle taper un nouvel élément ToDo, un bouton pour ajouter le nouvel élément à la liste et un ListBox pour afficher les éléments de la liste.

  1. Dans TodoWindow.xaml, supprimez les contrôles Button, TextBox et StackPanel de UserControl.

    Remarque

    Cela ne supprime pas le gestionnaire d’événements button1_Click , que vous réutiliserez ultérieurement.

  2. Dans la section Tous les contrôles WPF de la boîte à outils, faites glisser un contrôle Canvas vers la grille.

  3. Faites glisser une zone de texte, un bouton et une zone de liste vers le canevas. Organisez les éléments de façon à ce que textBox et le bouton se trouvent au même niveau, et le ListBox remplit le reste de la fenêtre en dessous, comme dans l’image ci-dessous.

    Finished Tool Window

  4. Dans le volet XAML, recherchez le bouton et définissez sa propriété Contenu sur Ajouter. Reconnectez le gestionnaire d’événements de bouton au contrôle Button en ajoutant un Click="button1_Click" attribut. Le bloc Canvas doit ressembler à ceci :

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

Personnaliser le constructeur

  1. Dans le fichier TodoWindowControl.xaml.cs , ajoutez la directive using suivante :

    using System;
    
  2. Ajoutez une référence publique à TodoWindow et avez le constructeur TodoWindowControl prendre un paramètre TodoWindow. Le code doit se présenter comme ceci :

    public TodoWindow parent;
    
    public TodoWindowControl(TodoWindow window)
    {
        InitializeComponent();
        parent = window;
    }
    
  3. Dans TodoWindow.cs, modifiez le constructeur TodoWindowControl pour inclure le paramètre TodoWindow. Le code doit se présenter comme ceci :

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

Créer une page Options

Vous pouvez fournir une page dans la boîte de dialogue Options afin que les utilisateurs puissent modifier les paramètres de la fenêtre outil. La création d’une page Options nécessite à la fois une classe qui décrit les options et une entrée dans le fichier TodoListPackage.cs ou TodoListPackage.vb .

  1. Ajoutez une classe nommée ToolsOptions.cs. Faire hériter la ToolsOptions classe de DialogPage.

    class ToolsOptions : DialogPage
    {
    }
    
  2. Ajoutez la directive using suivante :

    using Microsoft.VisualStudio.Shell;
    
  3. La page Options de cette procédure pas à pas ne fournit qu’une seule option nommée DaysAhead. Ajoutez un champ privé nommé daysAhead et une propriété nommée DaysAhead à la ToolsOptions classe :

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

    Vous devez maintenant prendre en compte le projet de cette page Options.

Mettre la page Options à la disposition des utilisateurs

  1. Dans TodoWindowPackage.cs, ajoutez une ProvideOptionPageAttribute à la TodoWindowPackage classe :

    [ProvideOptionPage(typeof(ToolsOptions), "ToDo", "General", 101, 106, true)]
    
  2. Le premier paramètre du constructeur ProvideOptionPage est le type de la classe ToolsOptionsque vous avez créée précédemment. Le deuxième paramètre, « ToDo », est le nom de la catégorie dans la boîte de dialogue Options . Le troisième paramètre, « Général », est le nom de la sous-catégorie de la boîte de dialogue Options dans laquelle la page Options sera disponible. Les deux paramètres suivants sont des ID de ressource pour les chaînes ; le premier est le nom de la catégorie, et le second est le nom de la sous-catégorie. Le paramètre final détermine si cette page est accessible à l’aide de l’automatisation.

    Lorsqu’un utilisateur ouvre votre page Options, il doit ressembler à l’image suivante.

    Options Page

    Notez la catégorie ToDo et le sous-catégorie Général.

Mettre les données à la disposition des Fenêtre Propriétés

Vous pouvez rendre les informations de liste ToDo disponibles en créant une classe nommée TodoItem qui stocke des informations sur les éléments individuels de la liste ToDo.

  1. Ajoutez une classe nommée TodoItem.cs.

    Lorsque la fenêtre outil est disponible pour les utilisateurs, les éléments de ListBox sont représentés par TodoItems. Lorsque l’utilisateur sélectionne l’un de ces éléments dans ListBox, la fenêtre Propriétés affiche des informations sur l’élément.

    Pour rendre les données disponibles dans la fenêtre Propriétés , vous transformez les données en propriétés publiques qui ont deux attributs spéciaux et DescriptionCategory. Description est le texte qui apparaît en bas de la fenêtre Propriétés . Category détermine l’emplacement où la propriété doit apparaître lorsque la fenêtre Propriétés est affichée dans la vue Catégorisée . Dans l’image suivante, la fenêtre Propriétés est en mode Catégorisé , la propriété Name de la catégorie Champs ToDo est sélectionnée et la description de la propriété Name s’affiche en bas de la fenêtre.

    Properties Window

  2. Ajoutez les directives using suivantes au fichier TodoItem.cs .

    using System.ComponentModel;
    using System.Windows.Forms;
    using Microsoft.VisualStudio.Shell.Interop;
    
  3. Ajoutez le modificateur d’accès public à la déclaration de classe.

    public class TodoItem
    {
    }
    

    Ajoutez les deux propriétés et NameDueDate. On fera le UpdateList() et CheckForErrors() plus tard.

    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. Ajoutez une référence privée au contrôle utilisateur. Ajoutez un constructeur qui accepte le contrôle utilisateur et le nom de cet élément ToDo. Pour rechercher la valeur pour daysAhead, elle obtient la propriété de la page Options.

    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. Étant donné que les instances de la TodoItem classe sont stockées dans ListBox et que ListBox appelle la ToString fonction, vous devez surcharger la ToString fonction. Ajoutez le code suivant à TodoItem.cs, après le constructeur et avant la fin de la classe.

    public override string ToString()
    {
        return name + " Due: " + dueDate.ToShortDateString();
    }
    
  6. Dans TodoWindowControl.xaml.cs, ajoutez des méthodes stub à la TodoWindowControl classe pour les méthodes et UpdateList les CheckForError méthodes. Placez-les après ProcessDialogChar et avant la fin du fichier.

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

    La CheckForError méthode appelle une méthode portant le même nom dans l’objet parent, et cette méthode case activée si des erreurs se sont produites et les gèrent correctement. La UpdateList méthode met à jour listBox dans le contrôle parent ; la méthode est appelée lorsque les Name propriétés de DueDate cette classe changent. Ils seront implémentés ultérieurement.

Intégrer à la Fenêtre Propriétés

Écrivez maintenant le code qui gère listBox, qui sera lié à la fenêtre Propriétés .

Vous devez modifier le gestionnaire de clics du bouton pour lire textBox, créer un TodoItem et l’ajouter à listBox.

  1. Remplacez la fonction existante button1_Click par du code qui crée un objet TodoItem et l’ajoute à ListBox. Il appelle TrackSelection(), qui sera défini ultérieurement.

    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. Dans la vue Création, sélectionnez le contrôle ListBox. Dans la fenêtre Propriétés , cliquez sur le bouton Gestionnaires d’événements et recherchez l’événement SelectionChanged . Renseignez la zone de texte avec listBox_SelectionChanged. Cela ajoute un stub pour un gestionnaire SelectionChanged et l’affecte à l’événement.

  3. Implémentez la méthode TrackSelection(). Étant donné que vous devrez obtenir les SVsUIShellSTrackSelection services, vous devez rendre l’accès GetService accessible par TodoWindowControl. Ajoutez la méthode suivante à la classe TodoWindow :

    internal object GetVsService(Type service)
    {
        return GetService(service);
    }
    
  4. Ajoutez les directives using suivantes à TodoWindowControl.xaml.cs :

    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Shell;
    
  5. Renseignez le gestionnaire SelectionChanged comme suit :

    private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        TrackSelection();
    }
    
  6. Maintenant, renseignez la fonction TrackSelection, qui fournira l’intégration à la fenêtre Propriétés . Cette fonction est appelée lorsque l’utilisateur ajoute un élément à ListBox ou clique sur un élément dans ListBox. Il ajoute le contenu de ListBox à un SelectionContainer et transmet le SelectionContainer au gestionnaire d’événements de OnSelectChange la fenêtre Propriétés. Le service TrackSelection effectue le suivi des objets sélectionnés dans l’interface utilisateur et affiche leurs propriétés

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

    Maintenant que vous disposez d’une classe que la fenêtre Propriétés peut utiliser, vous pouvez intégrer la fenêtre Propriétés à la fenêtre outil. Lorsque l’utilisateur clique sur un élément dans listBox dans la fenêtre outil, la fenêtre Propriétés doit être mise à jour en conséquence. De même, lorsque l’utilisateur modifie un élément ToDo dans la fenêtre Propriétés , l’élément associé doit être mis à jour.

  7. À présent, ajoutez le reste du code de la fonction UpdateList dans TodoWindowControl.xaml.cs. Il doit supprimer et rajouter l’objet TodoItem modifié à partir de ListBox.

    public void UpdateList(TodoItem item)
    {
        var index = listBox.SelectedIndex;
        listBox.Items.RemoveAt(index);
        listBox.Items.Insert(index, item);
        listBox.SelectedItem = index;
    }
    
  8. Testez votre code. Générez le projet et commencez le débogage. L’instance expérimentale doit apparaître.

  9. Ouvrez la page Options des outils>. Vous devez voir la catégorie ToDo dans le volet gauche. Les catégories sont répertoriées par ordre alphabétique, donc regardez sous les Ts.

  10. Dans la page des options de todo , vous devez voir la DaysAhead propriété définie sur 0. Remplacez-le par 2.

  11. Dans le menu Affichage / Autres fenêtres , ouvrez TodoWindow. Tapez EndDate dans la zone de texte, puis cliquez sur Ajouter.

  12. Dans la zone de liste, vous devriez voir une date de deux jours plus tard que aujourd’hui.

Ajouter du texte à la fenêtre Sortie et aux éléments à la liste des tâches

Pour la liste des tâches, vous créez un objet de type Task, puis ajoutez cet objet Task à la liste des tâches en appelant sa Add méthode. Pour écrire dans la fenêtre Sortie , vous appelez sa GetPane méthode pour obtenir un objet de volet, puis vous appelez la OutputString méthode de l’objet volet.

  1. Dans TodoWindowControl.xaml.cs, dans la méthode, ajoutez du button1_Click code pour obtenir le volet Général de la fenêtre Sortie (qui est la valeur par défaut) et écrivez-y. La méthode doit ressembler à ceci :

    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. Pour ajouter des éléments à la liste des tâches, vous devez ajouter une classe imbriquée à la classe TodoWindowControl. La classe imbriquée doit dériver de TaskProvider. Ajoutez le code suivant à la fin de la TodoWindowControl classe.

    [Guid("72de1eAD-a00c-4f57-bff7-57edb162d0be")]
    public class TodoWindowTaskProvider : TaskProvider
    {
        public TodoWindowTaskProvider(IServiceProvider sp)
            : base(sp)
        {
        }
    }
    
  3. Ajoutez ensuite une référence privée à TodoTaskProvider la classe et une CreateProvider() méthode.TodoWindowControl Le code doit se présenter comme ceci :

    private TodoWindowTaskProvider taskProvider;
    private void CreateProvider()
    {
        if (taskProvider == null)
        {
            taskProvider = new TodoWindowTaskProvider(parent);
            taskProvider.ProviderName = "To Do";
        }
    }
    
  4. Ajoutez ClearError(), qui efface la liste des tâches et ReportError(), qui ajoute une entrée à la liste des tâches, à la TodoWindowControl classe.

    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. Implémentez maintenant la CheckForErrors méthode, comme suit.

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

Faire un essai

  1. Générez le projet et commencez le débogage. L’instance expérimentale s’affiche.

  2. Ouvrez todoWindow (afficher>d’autres fenêtres>TodoWindow).

  3. Tapez un élément dans la zone de texte, puis cliquez sur Ajouter.

    Une date d’échéance de 2 jours après aujourd’hui est ajoutée à la zone de liste. Aucune erreur n’est générée et la liste des tâches (Afficher>la liste des tâches) ne doit pas avoir d’entrées.

  4. Modifiez maintenant le paramètre dans la page Options>d’outils>ToDo de 2 à 0.

  5. Tapez un autre élément dans TodoWindow, puis cliquez sur Ajouter à nouveau. Cela déclenche une erreur et une entrée dans la liste des tâches.

    Lorsque vous ajoutez des éléments, la date initiale est définie sur maintenant plus de 2 jours.

  6. Dans le menu Affichage , cliquez sur Sortie pour ouvrir la fenêtre Sortie .

    Notez que chaque fois que vous ajoutez un élément, un message s’affiche dans le volet Liste des tâches.

  7. Cliquez sur l’un des éléments dans listBox.

    La fenêtre Propriétés affiche les deux propriétés de l’élément.

  8. Modifiez l’une des propriétés, puis appuyez sur Entrée.

    L’élément est mis à jour dans listBox.