Partager via


Procédure pas - à - pas : Intégrant dans la fenêtre Propriétés, la liste des tâches, la fenêtre Sortie, et la boîte de dialogue options (partie de 4)

À l'aide de Kit de développement logiciel Visual Studio, vous pouvez permettre à votre code d'accéder à une fenêtre Outil dans Visual Studio. Par exemple, vous pouvez ajouter des entrées à Liste des tâches, ajouter du texte à la fenêtre de Sortie , ou intégrer votre extension dans la fenêtre de Propriétés afin que les utilisateurs puissent configurer l'extension en définissant des propriétés. Cette procédure pas - à - pas montre comment intégrer votre extension dans des fenêtres Outil dans Visual Studio.

En suivant cette procédure pas - à - pas, vous pouvez apprendre à effectuer les opérations suivantes :

  • Créez un VSPackage à l'aide de le modèle de package.

  • implémentez la fenêtre Outil générée.

  • Implémentez un gestionnaire de commandes de menu.

  • créez une page d'options.

  • rendez les données disponibles dans la fenêtre de Propriétés .

  • Intégrer dans la fenêtre Propriétés.

  • Ajoutez du texte à la fenêtre de Sortie et les éléments à Liste des tâches.

Cette procédure pas - à - pas fait partie d'une série de procédures qui explique comment étendre l'IDE de Visual Studio. Pour plus d'informations, consultez Procédures pas - à - pas pour personnaliser Visual Studio à l'aide de les VSPackages.

Composants requis

Pour exécuter cette procédure, vous devez installer Kit de développement logiciel Visual Studio 2010.

Notes

Pour plus d'informations sur le kit de développement Visual Studio, consultez Étendre la présentation de Visual Studio.Pour savoir comment télécharger le kit de développement Visual Studio, consultez Visual Studio Extensibility Developer Center sur le site Web MSDN.

Emplacements du modèle de projet de package Visual Studio

Le modèle de projet de package Visual Studio se trouve dans trois emplacements différents dans la boîte de dialogue Nouveau projet :

  1. Sous l'extensibilité Visual Basic. Le langage par défaut du projet est en Visual Basic.

  2. Sous l'extensibilité c#. Le langage par défaut du projet est c#.

  3. Sous d'autres projets contenus l'extensibilité. Le langage par défaut du projet est en C++.

Créez un VSPackage à l'aide de le modèle de package Visual Studio

pour créer un VSPackage

  1. créez un VSPackage. Pour plus d'informations sur la création d'un VSPackage, consultez Procédure pas - à - pas : Créer une commande de menu à l'aide de le modèle de package Visual Studio.

  2. Nommez le projet TodoList, définissez le langage en Visual c# ou en Visual Basic, et dans la page de Sélectionnez les options d'un VSPackage , sélectionnez Commande de menu et fenêtre Outil.

  3. sur la page d' options de commande , définissez nom de la commande à gestionnaire de Todo et ID de commande à cmdidTodoCommand.

  4. sur la page d' options de fenêtre Outil , définissez Nom de la fenêtre à gestionnaire de Todo et ID de commande à cmdidTodoTool.

  5. Cliquez sur le bouton Terminer.

implémentez la fenêtre Outil générée

Le modèle de package a généré une fenêtre Outil de base sous la forme d'un contrôle utilisateur. Toutefois, elle n'a pas de fonctionnalités. Pour lui affecter des fonctionnalités, vous devez ajouter des contrôles enfants et modifiez le code dans MyControl.xaml.cs ou MyControl.vb.

La fenêtre Outil inclut TextBox dans lequel vous pouvez taper un nouvel élément de ToDo, un Button le nouvel élément doit être ajouté à la liste, puis un ListBox pour afficher les éléments de la liste. La fenêtre Outil terminée doit ressembler à l'image suivante :

Fenêtre Outil fini

pour ajouter des contrôles à la fenêtre Outil

  1. Supprimez le bouton, le texte, les contrôles et de StackPanel de la grille.

    Notes

    Cela ne supprime pas le gestionnaire d'événements button1_Click, que vous réutiliserez dans une étape ultérieure.

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

  3. Faites glisser un contrôle de zone de texte, un contrôle bouton, et un contrôle listbox à la zone de dessin. Placez -les comme dans l'illustration ci-dessus.

  4. sélectionnez le bouton. définissez sa propriété de Contenu à ajoutez.

  5. Dans le volet XAML, reconnectez le gestionnaire d'événements du bouton au contrôle bouton en ajoutant attribut de Click= un " button1_Click ». La ligne résultante XAML doit ressembler à ceci :

    Public _parent As MyToolWindow
    Public Sub New(ByVal parent As MyToolWindow)
        InitializeComponent()
        _parent = parent
    End Sub
    
    <Button Content="Add" Height="21" Name="button1" Width="50" Canvas.Left="345" Canvas.Top="6" Click="button1_Click" />
    

    Enregistrez votre travail.

Par défaut, le constructeur du contrôle utilisateur dans le fichier de MyControl.xaml.cs ou de MyControl.xaml.vb ne prend pas de paramètres. Toutefois, vous pouvez personnaliser le constructeur pour inclure des paramètres afin de pouvoir enregistrer le parent pour une utilisation ultérieure.

pour personnaliser le constructeur

  1. De la page concepteur, cliquez avec le bouton droit sur Afficher le code.

  2. Remplacez le constructeur existant par le code suivant :

    public MyToolWindow _parent;
    public MyControl(MyToolWindow parent)
    {
        InitializeComponent();
        _parent = parent;
    }
    

    Cela permet au constructeur pour prendre un paramètre de type MyToolWindow.

  3. Enregistrez votre travail.

  4. Maintenant, ajoutez un paramètre au code qui appelle le constructeur.

    dans Explorateur de solutions, ouvrez MyToolWindow.cs ou MyToolWindow.vb.

  5. Recherchez la ligne dans le constructeur de MyToolWindow qui ressemble au code suivant.

    Me.Content = New MyControl()
    
    base.Content = new MyControl();
    
  6. modifiez la ligne comme suit.

    Me.Content = New MyControl(Me)
    
    base.Content = new MyControl(this);
    

    De cette façon passe l'instance de la fenêtre Outil au contrôle utilisateur. (Cela est requis dans une étape ultérieure pour créer le constructeur de la classe de ToDoItem.)

implémentez un gestionnaire de commande de menu

Lorsque le projet de TodoList a été créé, il inclut un gestionnaire par défaut de l'élément de menu. Le gestionnaire dans le fichier de TodoListPackage. Maintenant, ajoutez le code au gestionnaire pour afficher la fenêtre Outil. Vous pouvez le faire en quelques étapes car TodoListPackage contient déjà une fonction nommée ShowToolWindow.

Pour implémenter le gestionnaire d'éléments de menu

  1. ouvrez TodoListPackage.cs ou TodoListPackage.vb. Notez que le gestionnaire d'éléments de menu contient l'exemple de code suivant.

    Private Sub MenuItemCallback(ByVal sender As Object, ByVal e As EventArgs)
        ' Show a Message Box to prove we were here 
        Dim uiShell As IVsUIShell = TryCast(GetService(GetType(SVsUIShell)), IVsUIShell)
        Dim clsid As Guid = Guid.Empty
        Dim result As Integer
        Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(0, clsid, "TodoList", String.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", Me.GetType().Name), String.Empty, 0, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, OLEMSGICON.OLEMSGICON_INFO, 0, result))
    End Sub
    
    private void MenuItemCallback(object sender, EventArgs e)
    {
        // Show a Message Box to prove we were here
        IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
        Guid clsid = Guid.Empty;
        int result;
        Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(
                   0,
                   ref clsid,
                   "TodoList",
                   string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.ToString()),
                   string.Empty,
                   0,
                   OLEMSGBUTTON.OLEMSGBUTTON_OK,
                   OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                   OLEMSGICON.OLEMSGICON_INFO,
                   0,        // false 
                   out result));
    }
    
  2. supprimez tout dans la fonction, et remplacez-le par un appel à ShowToolWindow comme suit.

    Private Sub MenuItemCallback(ByVal sender As Object, ByVal e As EventArgs)
        ShowToolWindow(sender, e)
    End Sub
    
    private void MenuItemCallback(object sender, EventArgs e)
    {
        ShowToolWindow(sender, e);
    }        
    

    Enregistrez votre travail, puis appuyez sur F5 pour générer le projet et l'ouvrir dans la génération expérimentale de Visual Studio. Test si la fenêtre Outil s'ouvre en cliquant sur gestionnaire de ToDo dans le menu d' Outils .

    Fermez la génération expérimentale avant de continuer.

créez une page d'options

Vous pouvez fournir une page de la boîte de dialogue d' Options afin que les utilisateurs puissent modifier des paramètres de la fenêtre Outil. Création d'une page d'options requiert une classe qui décrit les options et une entrée dans le fichier de TodoListPackage.cs ou de TodoListPackage.vb.

pour créer une page d'options

  1. Dans Explorateur de solutions, cliquez avec le bouton droit sur le projet de ToDoList, pointez sur Ajouter, puis cliquez sur Classe.

  2. Dans la boîte de dialogue d' Ajouter un nouvel élément , nommez le fichier ToolsOptions.cs, ou ToolsOptions.vb puis cliquez sur Ajouter.

    Visual Studio crée une classe nommée ToolsOptions dans ce fichier, mais vous devez modifier l'en-tête de la classe afin que la classe est dérivée d' DialogPage.

    Ajoutez l'espace de noms d' Microsoft.VisualStudio.Shell à exister à l'aide de/directives d'importations, comme suit.

    Imports Microsoft.VisualStudio.Shell
    
    using Microsoft.VisualStudio.Shell;
    
  3. modifiez la déclaration de classe d' ToolsOptions pour hériter d' DialogPage.

    Inherits DialogPage
    
    class ToolsOptions : DialogPage
    
  4. La page d'options dans cette procédure pas - à - pas fournit uniquement un DaysAhead nommé par option. pour ajouter cette option, ajoutez une propriété nommée DaysAhead à la classe de ToolsOptions comme suit.

    Private _daysAhead As Double 
    
    Public Property DaysAhead() As Double 
        Get 
            Return _daysAhead
        End Get 
        Set(ByVal value As Double)
            _daysAhead = value
        End Set 
    End Property
    
    private double _daysAhead;
    
    public double DaysAhead
    {
        get { return _daysAhead; }
        set { _daysAhead = value; }
    }
    

    Cette classe stocke une option unique comme membre privé nommé _daysAhead. La classe fournit ensuite une propriété publique nommée DaysAhead pour accéder à l'option.

  5. Enregistrez le fichier.

Maintenant vous devez informer le projet de cette page d'options pour qu'elle soit inscrite convenablement et à la disposition des utilisateurs.

Pour rendre la page d'options disponibles aux utilisateurs

  1. dans explorateur de solutions, ouvrez TodoListPackage.cs ou TodoListPackage.vb.

  2. Recherchez la ligne qui contient l'attribut d' ProvideToolWindowAttribute , puis ajoutez un attribut d' ProvideOptionPageAttribute directement après, comme suit.

    <PackageRegistration(UseManagedResourcesOnly:=True), _
    InstalledProductRegistration("#110", "#112", "1.0", IconResourceID:=400), _
    ProvideMenuResource("Menus.ctmenu", 1), _
    ProvideToolWindow(GetType(MyToolWindow)), _
    ProvideOptionPage(GetType(ToolsOptions), "To-Do", "General", 101, 106, True), _
    Guid(GuidList.guidTodoListPkgString)> _
    Public NotInheritable Class TodoListPackage
        Inherits Package
    
    [ProvideToolWindow(typeof(MyToolWindow))]
    [ProvideOptionPage(typeof(ToolsOptions), "To-Do", "General", 101, 106, true)]
    

    Notes

    Vous ne devez pas inclure le mot « attribut » dans les déclarations attribute.

  3. Enregistrez le fichier.

    Le premier paramètre au constructeur de ProvideOptionPage est le type de la classe ToolsOptions, que vous avez créée précédemment. Le deuxième paramètre, des « tâches », le nom de la catégorie de la boîte de dialogue d' Options . le troisième paramètre, « général », est le nom du sous-catégorie de la boîte de dialogue d' Options où la page d'options sera disponible. Les deux paramètres suivants sont des identificateurs de ressource pour les chaînes ; le premier est le nom de la catégorie, et le second est le nom de sous-catégorie. Les jeux de paramètres ultimes si cette page peut être accessible à l'aide de l'automation.

    Lorsque votre page d'options sont accessibles, elle doit ressembler à l'image suivante.

    Page Options

    Remarquez les tâches de catégorie et la sous-catégorie général de.

rendez les données disponibles dans la fenêtre Propriétés

Par les principes suivants pour une bonne conception orientée objet, vous pouvez faire une classe nommée ToDoItem qui stocke des informations sur les différents éléments dans la liste des tâches.

pour rendre des données disponibles dans la fenêtre Propriétés

  1. Dans Explorateur de solutions, cliquez avec le bouton droit sur le projet de ToDoList, pointez sur Ajouter, puis cliquez sur Classe.

  2. Dans la boîte de dialogue d' Ajouter un nouvel élément , nommez le fichier ToDoItem.cs ou ToDoItem.vb, puis cliquez sur Ajouter.

    Lorsque la fenêtre Outil est disponible aux utilisateurs, les éléments de la zone de liste sont représentés par des instances de ToDoItem. Lorsque l'utilisateur sélectionne un de ces éléments de la zone de liste, la fenêtre de Propriétés affiche des informations sur l'élément.

    Pour rendre des données disponibles dans la fenêtre de Propriétés , transformez les données en propriétés publiques d'une classe puis documentez-les à l'aide de deux attributs, descriptions et catégories spécifiques. La description est le texte affiché en bas de la fenêtre de Propriétés . La catégorie définit où la propriété doit s'afficher lorsque la fenêtre de Propriétés s'affiche dans la vue par catégorie. Dans l'image suivante, la fenêtre de Propriétés est dans la vue par catégorie, la propriété de Nom dans la catégorie de champs de tâches est sélectionnée, et la description de la propriété de Nom est affichée au bas de la fenêtre.

    Fenêtre Propriétés

  3. Ajoutez les espaces de noms suivants au début du fichier de ToDoItem.cs ou de ToDoItem.vb, une fois qu'un existant à l'aide de/instructions imports.

    Imports System.ComponentModel
    Imports System.Windows.Forms
    Imports Microsoft.VisualStudio.Shell.Interop
    
    using System.ComponentModel;
    using System.Windows.Forms;
    using Microsoft.VisualStudio.Shell.Interop;
    
  4. Démarrez en implémentant la classe de ToDoItem comme suit. veillez à ajouter le modificateur d'accès d' public à la déclaration de classe.

    Private _name As String
    <Description("Name of the To-Do item")> _
    <Category("To-Do Fields")> _
    Public Property Name() As String 
        Get 
            Return _name
        End Get 
        Set(ByVal value As String)
            _name = value
            _parent.UpdateList(Me)
        End Set 
    End Property 
    
    Private _dueDate As Date
    <Description("Due date of the To-Do item")> _
    <Category("To-Do Fields")> _
    Public Property DueDate() As Date 
        Get 
            Return _dueDate
        End Get 
        Set(ByVal value As Date)
            _dueDate = value
            _parent.UpdateList(Me)
            _parent.CheckForErrors()
        End Set 
    End Property
    
    public class ToDoItem
    {
        private string _name;
        [Description("Name of the To-Do item")]
        [Category("To-Do Fields")]
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                _parent.UpdateList(this);
            }
        }
    
        private DateTime _dueDate;
        [Description("Due date of the To-Do item")]
        [Category("To-Do Fields")]
        public DateTime DueDate
        {
            get { return _dueDate; }
            set
            {
                _dueDate = value;
                _parent.UpdateList(this);
                _parent.CheckForErrors();
            }
        }
    }
    

    Remarquez que le code a deux propriétés, noms et DueDate. Ce sont les deux propriétés qui s'affichent dans la fenêtre de Propriétés , comme indiqué dans l'image précédente. Chaque propriété est précédée par les attributs de description et de catégorie, qui fournissent des informations sur l'affichage dans la fenêtre de Propriétés . examinez ces deux attributs pour la propriété Name ; les chaînes doivent correspondre à celles de l'image.

  5. ajoutez la fonction constructeur suivante en haut de la classe.

    Private _parent As MyControl
    Public Sub New(ByVal parent As MyControl, ByVal name As String)
        _parent = parent
        _name = name
        _dueDate = Date.Now
    
        Dim daysAhead As Double = 0
        Dim package As IVsPackage = TryCast(_parent._parent.Package, IVsPackage)
        If package IsNot Nothing Then 
            Dim obj As Object
            package.GetAutomationObject("To-Do.General", obj)
    
            Dim options As ToolsOptions = TryCast(obj, ToolsOptions)
            If options IsNot Nothing Then
                daysAhead = options.DaysAhead
            End If 
        End If
    
        _dueDate = _dueDate.AddDays(daysAhead)
    End Sub
    
    private MyControl _parent;
    public ToDoItem(MyControl parent, string name)
    {
        _parent = parent;
        _name = name;
        _dueDate = DateTime.Now;
    
        double daysAhead = 0;
        IVsPackage package = _parent._parent.Package as IVsPackage;
        if (package != null)
        {
            object obj;
            package.GetAutomationObject("To-Do.General", out obj);
    
            ToolsOptions options = obj as ToolsOptions;
            if (options != null)
            {
                daysAhead = options.DaysAhead;
            }
        }
    
        _dueDate = _dueDate.AddDays(daysAhead);
    }
    

    D'abord, ce code déclare un membre privé nommé _parent, qui correspond au contrôle utilisateur qui contient les contrôles de zone de texte, de boutons, et zone de liste que vous avez créés précédemment. Le constructeur prend le contrôle utilisateur comme paramètre, avec une chaîne qui est le nom de cet élément de ToDo. Les trois premières lignes de la sauvegarde de constructeur le contrôle utilisateur, le nom, et la date et l'heure actuelles.

    Vous pouvez utiliser la date et l'heure actuelles comme base d'activer l'option de DaysAhead sur la page d'option que vous avez créée précédemment. Étant donné que la date et l'heure actuelles ne sont pas généralement utilisées comme date d'échéance, vous pouvez replacer la date actuelle par le nombre de jours qui sont spécifiés dans la page d'options. .

    Le code déclare une variable locale appelée daysAhead définie à l'aide de la valeur de l'option de DaysAhead. La ligne suivante obtient le parent du contrôle utilisateur et, de là, le membre de package. (C'est là où vous utilisez le membre _parent que vous avez ajouté à la classe de MyControl.xaml.cs précédemment.)

    Si ce membre de package n'est pas nul, il déclare un objet qui contiendra l'instance de ToolsOptions. Pour recevoir l'instance, le code appelle le membre de GetAutomationObject du package et passe le nom de la catégorie et la sous-catégorie comme une chaîne point-délimitée unique, To-Do.General. Les résultats sont passés comme paramètre de sortie dans la variable obj.

    La variable obj est ensuite cast à la classe de ToolsOptions et stocké dans une variable nommée options. Si cette variable n'est pas nul, le code obtient le membre d' DaysAhead et le stocke dans la variable d' _daysAhead .

    Le code avance la variable d'duedate _par le nombre de jours en avant à l'aide de la méthode d' AddDays .

  6. Dans la mesure où les instances de la classe d' ToDoItem seront enregistrés dans la zone de liste et de la zone de liste appelle la fonction d' ToString que cette classe hérite de la classe de base d' Object pour récupérer la chaîne à afficher pour l'élément, vous devez surcharger la fonction d' ToString .

    Ajoutez le code suivant à ToDoItem.cs, après le constructeur et avant la fin de la classe.

    Public Overloads Overrides Function ToString() As String 
        Return (_name & " Due: ") + _dueDate.ToShortDateString()
    End Function
    
    public override string ToString()
    {
        return _name + " Due: " + _dueDate.ToShortDateString();
    }
    
  7. ouvrez MyControl.xaml.cs ou MyControl.xaml.vb.

  8. ajoutez les méthodes stub à la classe de MyControl pour les méthodes d' CheckForError et d' UpdateList . Placez -les après le ProcessDialogChar et avant la fin de le fichier.

    Public Sub CheckForErrors()
    
    End Sub 
    
    Public Sub UpdateList(ByVal item As ToDoItem)
    
    End Sub
    Public Sub CheckForErrors()
    
    End Sub 
    
    Public Sub UpdateList(ByVal item As ToDoItem)
    
    End Sub
    
    public void CheckForErrors()
    {
    }
    public void UpdateList(ToDoItem item)
    {
    }
    

    La méthode d' CheckForError appelle une méthode qui a le même nom dans l'objet parent, et que la méthode vérifie si des erreurs se sont produites et les gérer correctement. La méthode d' UpdateList met à jour la zone de liste dans le contrôle parent ; la méthode est appelée lorsque les propriétés d' Name et d' DueDate dans cette classe sont modifiées. Vous implémenterez ces méthodes dans une étape ultérieure.

Intégrer dans la fenêtre Propriétés

Écrire le code qui gère la zone de liste, qui sera liée à la fenêtre de Propriétés .

Vous devez ajouter un handle du bouton qui indique la zone de texte, crée une instance de ToDoItem, et ajoute l'instance à la zone de liste.

pour intégrer avec la fenêtre Propriétés

  1. Basculez en mode Design de MyControl.xaml, double-cliquez sur le contrôle button

  2. Remplacez la fonction gestionnaire existante d' button1_Click à l'aide de le code suivant.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        If TextBox1.Text.Length > 0 Then 
            Dim item = New ToDoItem(Me, TextBox1.Text)
            ListBox1.Items.Add(item)
            TrackSelection()
            CheckForErrors()
        End If 
    End Sub
    
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions")]
    private void button1_Click(object sender, EventArgs e)
    {
        if (textBox1.Text.Length > 0)
        {
            var item = new ToDoItem(this, textBox1.Text);
            listBox1.Items.Add(item);
            TrackSelection();
            CheckForErrors();
        }
    }
    

    Ce code crée une nouvelle instance de ToDoItem et passe l'instance de contrôle utilisateur comme paramètre avec le texte que l'utilisateur a entré dans le contrôle de zone de texte. Ensuite, le code ajoute l'élément à la zone de liste. (La zone de liste appelle la méthode ToString d'instance de ToDoItem pour récupérer la chaîne à afficher dans la zone de liste.) Ensuite, le code appelle la fonction de TrackSelection, que vous écrirez à une étape ultérieure. Enfin, les contrôles de programmation pour les erreurs.

  3. Basculez en mode Design de MyControl.xaml pour ajouter du code qui gère la sélection utilisateur d'un nouvel élément dans la zone de liste.

  4. Cliquez sur le contrôle listbox. Dans la fenêtre de Propriétés , double-cliquez sur l'événement de SelectionChanged. De cette façon ajoute un stub pour un gestionnaire de SelectionChanged et l'assigne à l'événement.

  5. Exécutez le gestionnaire de SelectionChanged comme suit, et le stub de la méthode qu'il appelle.

    Private Sub ListBox1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ListBox1.SelectionChanged
        TrackSelection()
    End Sub 
    
    Private Sub TrackSelection()
    
    End Sub
    
    private void listBox1_SelectionChanged(object sender, EventArgs e)
    {
        TrackSelection();
    }
    private void TrackSelection()
    {
    }
    
  6. Enregistrez votre travail. Vous pouvez générer votre projet et rechercher des typos.

  7. maintenant, complétez la fonction de TrackSelection, qui fournira à l'intégration la fenêtre de Propriétés . Cette fonction est appelée lorsque l'utilisateur ajoute un élément à la zone de liste ou clique sur un élément dans la zone de liste.

    Maintenant que vous avez une classe que la fenêtre de Propriétés peut utiliser, vous pouvez intégrer la fenêtre de Propriétés avec la fenêtre d'Outil. Lorsque l'utilisateur clique sur un élément dans la zone de liste de la fenêtre Outil, la fenêtre de Propriétés doit être mis à jour en conséquence. De même, lorsque l'utilisateur modifie un élément de ToDo dans la fenêtre de Propriétés , l'élément associé doit être mis à jour.

    Notes

    Sinon, vous pouvez générer des événements d' PropertyChanged directement en implémentant l'interface d' INotifyPropertyChanged .

    Placez le code pour mettre à jour la fenêtre de Propriétés dans la fonction de TrackSelection. Cela lier l'objet de ToDoItem dans la fenêtre de Propriétés ; vous n'avez pas à écrire de code supplémentaire pour modifier le ToDoItem lorsque l'utilisateur modifie une valeur dans la fenêtre de Propriétés . La fenêtre de Propriétés appelle automatiquement les accesseurs de propriété d' set pour mettre à jour les valeurs. Toutefois, vous devez terminer la méthode d'UpdateList que vous avez créée lorsque vous avez écrit le code pour la classe de ToDoItem.

  8. Ajoutez les déclarations d'espaces de noms suivantes au début du fichier de MyControl.xaml.cs ou de MyControl.vb, une fois qu'un existant à l'aide de/instructions imports.

    Imports System
    Imports System.Runtime.InteropServices
    Imports Microsoft.VisualStudio.Shell.Interop
    Imports Microsoft.VisualStudio
    Imports Microsoft.VisualStudio.Shell
    
    using System.Runtime.InteropServices;
    using Microsoft.VisualStudio.Shell.Interop;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Shell;
    
  9. implémentez la fonction de TrackSelection comme suit.

    Private mySelContainer As SelectionContainer
    Private mySelItems As System.Collections.ArrayList
    Private frame As IVsWindowFrame = Nothing 
    Private Sub TrackSelection()
        If frame Is Nothing Then 
            Dim shell = TryCast(GetService(GetType(SVsUIShell)), IVsUIShell)
            If shell IsNot Nothing Then 
                Dim guidPropertyBrowser = New Guid(ToolWindowGuids.PropertyBrowser)
                shell.FindToolWindow(CUInt(__VSFINDTOOLWIN.FTW_fForceCreate), guidPropertyBrowser, frame)
            End If 
        End If 
        If frame IsNot Nothing Then
            frame.Show()
        End If 
        If mySelContainer Is Nothing Then
            mySelContainer = New SelectionContainer()
        End If
    
        mySelItems = New System.Collections.ArrayList()
    
        Dim selected = TryCast(listBox1.SelectedItem, ToDoItem)
        If selected IsNot Nothing Then
            mySelItems.Add(selected)
        End If
    
        mySelContainer.SelectedObjects = mySelItems
    
        Dim track = TryCast(GetService(GetType(STrackSelection)), ITrackSelection)
        If track IsNot Nothing Then
            track.OnSelectChange(mySelContainer)
        End If 
    End Sub
    
    private SelectionContainer mySelContainer;
    private System.Collections.ArrayList mySelItems;
    private IVsWindowFrame frame = null;
    
    private void TrackSelection()
    {
        if (frame == null)
        {
            var shell = GetService(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 = listBox1.SelectedItem as ToDoItem;
        if (selected != null)
        {
            mySelItems.Add(selected);
        }
    
        mySelContainer.SelectedObjects = mySelItems;
    
        var track = GetService(typeof(STrackSelection))
            as ITrackSelection;
        if (track != null)
        {
            track.OnSelectChange(mySelContainer);
        }
    }        
    
  10. Ajoutez le code suivant juste après la fin de la fonction de TrackSelection.

    Protected Function GetService(ByVal service As Type) As Object 
        Dim obj As Object = Nothing 
        If _parent IsNot Nothing Then
            obj = _parent.GetVsService(service)
        End If 
        Return obj
    End Function
    
    protected object GetService(Type service)
    {
        if (_parent != null)
        {
            return _parent.GetVsService(service);
        }
        return null;
    }
    

    Ce code appelle la fonction GetService. Essaie de cette fonction d'abord pour obtenir le service de la fenêtre Outil parente en appelant sa fonction GetService. En cas de échec, il essaie de l'obtenir à partir de la fonction GetService de l'objet. Étant donné que la fonction GetService dans la fenêtre Outil parent n'est pas publique, le code appelle GetVsService à la place. vous devez ajouter la fonction de GetVsService.

  11. ouvrez MyToolWindow.cs ou MyToolWindow.vb. Ajoutez le code suivant à la fin de la classe, juste avant la fin de le fichier.

    Friend Function GetVsService(ByVal service As Type) As Object 
        Return GetService(service)
    End Function
    
    internal object GetVsService(Type service)
    {
        return GetService(service);
    }
    
  12. Enregistrez le fichier.

    La première fois que la fonction de TrackSelection s'exécute, elle appelle GetService pour obtenir une instance du shell de Visual Studio . Il utilise ensuite qui instance pour obtenir un objet pour la fenêtre de Propriétés . Pour obtenir l'objet window de Propriétés , le démarrage du code à l'aide d'un GUID qui représente la fenêtre de Propriétés . (Les GUID pour les fenêtres Outil sont des membres de la classe d' ToolWindowGuids80 .) Le code appelle ensuite la fonction de FindToolWindow du shell, en passant GUID, pour obtenir l'objet window de Propriétés . De cette façon le stocke dans la variable frame de sorte que lorsque la fonction est appelée de nouveau, ce processus d'obtenir la fenêtre de Propriétés ne doit pas être répété.

    Suivant, la méthode appelle la méthode show de variable frame pour afficher la fenêtre de Propriétés .

    Le code suivant rassemble les éléments sélectionnés dans la zone de liste. La zone de liste n'est pas configuré pour activer la sélection multiple. Pour passer l'élément sélectionné dans la fenêtre de Propriétés , vous devez utiliser un conteneur. Par conséquent, le code rassemble l'élément sélectionné et la place dans un ArrayList, puis met cet ArrayList dans un conteneur de type SelectionContainer.

    Ensuite, le code appelle GetService pour obtenir une instance d'ITrackSelection, qui est l'objet de Visual Studio que ces pistes ont sélectionné les objets dans l'interface (UI) utilisateur et affichent leurs propriétés. Le code appelle directement le gestionnaire d'événements d'ITrackSelection OnSelectChange, et passe le SelectionContainer qui contient l'élément sélectionné. Le résultat est que la fenêtre de Propriétés affiche les propriétés de l'élément sélectionné.

    Lorsque l'utilisateur modifie un objet de ToDoItem dans la fenêtre de Propriétés , la fenêtre de Propriétés appelle automatiquement les fonctions d'accesseur d' set dans l'objet de ToDoItem. Ce met à jour l'objet, mais vous devez toujours mettre à jour la zone de liste.

  13. Dans une étape précédente, vous avez ajouté le code dans les fonctions d'accesseur d' set pour appeler une fonction d'UpdateList dans MyControl.xaml.cs ou MyControl.xaml.vb. Maintenant, ajoutez le reste du code de fonction d'UpdateList.

  14. De MyControl.xaml.cs ou de MyControl.xaml.vb, implémentez la méthode d'UpdateList comme suit.

    Public Sub UpdateList(ByVal item As ToDoItem)
        Dim index As Integer = ListBox1.SelectedIndex
        listBox1.Items.RemoveAt(index)
        listBox1.Items.Insert(index, item)
        ListBox1.SelectedItem = index
    End Sub
    
    public void UpdateList(ToDoItem item)
    {
        var index = listBox1.SelectedIndex;
        listBox1.Items.RemoveAt(index);
        listBox1.Items.Insert(index, item);
        listBox1.SelectedItem = index;
    }
    

    Ce code détermine quel élément est sélectionné et correspond au ToDoItem modifié. Le code supprime l'élément de la zone de liste, puis le réinsère. De cette façon met à jour la ligne de la zone de liste pour l'élément. Puis le code définit la sélection sur le même élément.

  15. Enregistrez votre travail.

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

Pour ajouter des chaînes à la fenêtre de Liste des tâches et de Sortie , vous devez d'abord obtenir les objets qui font référence à ces deux fenêtres. Ensuite, vous pouvez appeler des méthodes sur des objets. Pour Liste des tâches, vous créez un objet de tâche de type, puis ajoutez cet objet de tâche à Liste des tâches en appelant son ajoutez la méthode. Pour écrire dans Sortie la fenêtre, vous appelez sa méthode de GetPane pour obtenir un objet de volet, puis vous appelez la méthode d'OutputString d'objet de volet.

Pour ajouter du texte à la fenêtre Sortie et à la liste des tâches

  1. ouvrez MyControl.xaml.cs ou MyControl.xaml.vb.

  2. Développez la méthode button1_Click en insérant le code suivant avant l'appel à TrackSelection().

    Dim outputWindow = TryCast(GetService(GetType(SVsOutputWindow)), IVsOutputWindow)
    Dim pane As IVsOutputWindowPane
    Dim guidGeneralPane As Guid = VSConstants.GUID_OutWindowGeneralPane
    outputWindow.GetPane(guidGeneralPane, pane)
    If pane IsNot Nothing Then
        pane.OutputString(String.Format("To Do item created: {0} \r\n", item.ToString()))
    End If
    
    private void button1_Click(object sender, EventArgs e)
    {
        if (textBox1.Text.Length > 0)
        {
            var item = new ToDoItem(this, textBox1.Text);
            listBox1.Items.Add(item);
    
            //Insert this section------------------ 
            var outputWindow = GetService(
                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();
        }
    

    ce code obtient l'objet pour la fenêtre de Sortie . l'objet expose une interface d'IVsOutputWindow. Le code obtient ensuite un objet d'IVsOutputWindowPane qui inclut la fonction d'OutputString, qui écrit finalement à Sortie la fenêtre.

  3. appliquez maintenant la méthode de CheckForErrors, comme suit.

    Public Sub CheckForErrors()
        For Each item As ToDoItem In ListBox1.Items
            If item.DueDate < DateTime.Now Then
                ReportError("To Do Item is out of date: " & item.ToString())
            End If 
        Next 
    End Sub
    
    public void CheckForErrors()
    {
        foreach (ToDoItem item in listBox1.Items)
        {
            if (item.DueDate < DateTime.Now)
            {
                ReportError("To Do Item is out of date: "
                    + item.ToString());
            }
        }
    }
    

    Ce code appelle la méthode de ReportError, que vous créerez ensuite, ainsi que d'autres méthodes permettant d'ajouter des éléments à Liste des tâches.

  4. Ajoutez le code suivant à la fin de la classe, juste avant les deux accolades fermantes.

    <Guid("72de1eAD-a00c-4f57-bff7-57edb162d0be")> _
    Public Class MyTaskProvider
        Inherits TaskProvider
        Public Sub New(ByVal sp As IServiceProvider)
            MyBase.New(sp)
        End Sub 
    End Class 
    Private _taskProvider As MyTaskProvider
    Private Sub CreateProvider()
        If _taskProvider Is Nothing Then
            _taskProvider = New MyTaskProvider(_parent)
            _taskProvider.ProviderName = "To Do" 
        End If 
    End Sub 
    Private Sub ClearError()
        CreateProvider()
        _taskProvider.Tasks.Clear()
    End Sub 
    Private Sub ReportError(ByVal p As String)
        CreateProvider()
        Dim errorTask = New Task()
        errorTask.CanDelete = False
        errorTask.Category = TaskCategory.Misc
        errorTask.Text = p
    
        _taskProvider.Tasks.Add(errorTask)
    
        _taskProvider.Show()
    
        Dim taskList = TryCast(GetService(GetType(SVsTaskList)), IVsTaskList2)
        If taskList Is Nothing Then 
            Exit Sub 
        End If 
    
        Dim guidProvider = GetType(MyTaskProvider).GUID
        taskList.SetActiveProvider(guidProvider)
    End Sub
    
    [Guid("72de1eAD-a00c-4f57-bff7-57edb162d0be")]
    public class MyTaskProvider : TaskProvider
    {
        public MyTaskProvider(IServiceProvider sp)
            : base(sp)
        {
        }
    }
    private MyTaskProvider _taskProvider;
    private void CreateProvider()
    {
        if (_taskProvider == null)
        {
            _taskProvider = new MyTaskProvider(_parent);
            _taskProvider.ProviderName = "To Do";
        }
    }
    private void ClearError()
    {
        CreateProvider();
        _taskProvider.Tasks.Clear();
    }
    private void ReportError(string p)
    {
        CreateProvider();
        var errorTask = new Task();
        errorTask.CanDelete = false;
        errorTask.Category = TaskCategory.Misc;
        errorTask.Text = p;
    
        _taskProvider.Tasks.Add(errorTask);
    
        _taskProvider.Show();
    
        var taskList = GetService(typeof(SVsTaskList))
            as IVsTaskList2;
        if (taskList == null)
        {
            return;
        }
    
        var guidProvider = typeof(MyTaskProvider).GUID;
        taskList.SetActiveProvider(ref guidProvider);
    }
    

    Au début de ce code est un TaskProvider spécialisé MyTaskProvider nommé par classe qui inclut un GUID. Suivante est une variable membre de ce nouveau type de classe, si vous avez suivi par une méthode qui crée la nouvelle instance lorsqu'il est requis.

    Suivant l'origine deux méthodes, ClearError, qui désactive les tâches existantes, et ReportError importants, qui ajoute des éléments à Liste des tâches.

    La méthode de ReportError crée une nouvelle instance de tâche, initialise l'instance, puis ajoute l'instance à Liste des tâches. Les nouvelles entrées de Liste des tâches sont uniquement visibles lorsque l'utilisateur sélectionne l'élément de ToDo dans la liste déroulante en haut de Liste des tâches. Les deux lignes finales code sélectionnent automatiquement l'élément de ToDo dans la liste déroulante et présentent les nouvelles tâches dans l'affichage. GUID est requis lorsque la classe de TaskProvider est héritée car la méthode de SetActiveProvider requiert un GUID comme paramètre.

En tentant

Pour tester l'extension

  1. appuyez sur CTRL+F5 pour ouvrir la génération expérimentale de Visual Studio.

  2. Dans la génération expérimentale, dans le menu d' Outils , cliquez sur gestionnaire de ToDo.

    La fenêtre Outil que vous avez conçue doit s'ouvrir.

  3. Tapez du texte dans la zone de texte puis cliquez sur Ajouter.

    Vous devez voir que l'élément est ajouté à la zone de liste.

  4. Tapez autre chose puis cliquez sur Ajouter de nouveau.

    Lorsque vous ajoutez des éléments, la date de démarrage a pour valeur la date et l'heure actuelles. Cela génère une erreur et également une entrée dans Liste des tâches.

  5. Dans le menu d' Afficher , cliquez sur Sortie pour ouvrir la fenêtre de Sortie .

    Notez que chaque fois que vous ajoutez un élément, un message est affiché dans le volet de Liste des tâches .

  6. Cliquez sur l'un des éléments dans la zone de liste.

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

  7. La modification l'une des propriétés et appuyez sur ENTRÉE.

    l'élément est mis à jour dans la zone de liste.

Quoi d'autre ?

Dans cette procédure pas - à - pas vous avez créé une fenêtre Outil qui est intégrée à une autre fenêtre Outil dans Visual Studio. Visual Studio a plusieurs fenêtres Outil avec lesquels vous pouvez travailler, et les GUID pour celles-ci se trouve dans la classe d' ToolWindowGuids . Vous avez également créé une classe qui contient les propriétés auxquelles la fenêtre de Propriétés peut accéder. vous avez fourni les fonctions d'accesseur que la fenêtre de Propriétés utilise. Dans la fonction d'accesseur d' set, vous avez appelé dans votre propre code pour gérer les modifications apportées dans la fenêtre de Propriétés . Cela fournit un mécanisme de communication bidirectionnelle. Enfin, vous avez appris à ajouter des éléments à Liste des tâches, comment entrer des éléments dans l'affichage, et comment ajouter du texte à la fenêtre de Sortie .

Voir aussi

Concepts

Fenêtre Sortie (kit de développement Visual Studio SDK)

liste des tâches

Autres ressources

commandes, menus, et barres d'outils

fenêtres Outil

fenêtre Propriétés et pages de propriétés