Compartilhar via


Passo a passo: Integrando a janela Propriedades, lista de tarefas, a janela de saída e caixa de diálogo Opções (parte 4 de 4)

Usando o SDK do Visual Studio, você pode habilitar o seu código para acessar qualquer janela de ferramenta em Visual Studio. Por exemplo, você pode adicionar entradas para o Lista de tarefas, adicionar texto ao saída janela, ou integrar sua extensão para o Propriedades janela para que os usuários podem configurar a extensão, definindo propriedades. Esta explicação passo a passo mostra como integrar sua extensão em janelas de ferramentas em Visual Studio.

Ao concluir este passo a passo, você pode aprender a fazer o seguinte:

  • Crie um VSPackage usando o modelo de pacote.

  • Implemente a janela da ferramenta gerado.

  • Implemente um manipulador de comandos de menu.

  • Crie uma página de opções.

  • Tornar dados disponíveis para o Propriedades janela.

  • Integre a janela Propriedades.

  • Adicionar texto para o saída janela e itens para Lista de tarefas.

Esta explicação passo a passo é parte de uma série que ensina como estender o IDE de Visual Studio. Para obter mais informações, consulte Explicações passo a passo para personalizar Visual Studio usando VSPackages.

Pré-requisitos

Para concluir este passo a passo, você deve instalar o SDL do Visual Studio 2010.

Dica

Para obter mais informações sobre o SDK de Visual Studio, consulte Ampliando a visão geral de Visual Studio.Para descobrir como fazer o download do SDK do Visual Studio, consulte Visual Studio extensibilidade Developer Center no site do MSDN.

Locais para o modelo de projeto de pacote de Visual Studio

O modelo de projeto do pacote de Visual Studio pode ser encontrado em três locais diferentes de Novo projeto caixa de diálogo:

  1. Em Visual Basic extensibilidade. O idioma padrão do projeto é Visual Basic.

  2. Em C# extensibilidade. O idioma padrão do projeto é C#.

  3. Em outra extensibilidade de tipos de projeto. O idioma padrão do projeto é C++.

Criar um VSPackage usando o modelo de pacote de Visual Studio

Para criar um VSPackage

  1. Crie um VSPackage. Para obter mais informações sobre como criar um VSPackage, consulte Passo a passo: Criando um comando de Menu usando o modelo de pacote de Visual Studio.

  2. Nomeie o projeto lista de tarefas do, definir o idioma Visual C# ou Visual Basic e na Selecionar opções de VSPackage , selecione ambos Comando de Menu e Janela da ferramenta.

  3. No Opções de comando de página, defina nome do comando para Gerenciador de Todo e ID do comando para cmdidTodoCommand.

  4. No Janela Opções da ferramenta de página, defina nome da janela para Gerenciador de Todo e ID do comando para cmdidTodoTool.

  5. Clique no Concluir botão.

Implementar a janela da ferramenta gerado

O modelo de pacote gerado uma janela de ferramenta básica na forma de um controle de usuário. No entanto, ele tem nenhuma funcionalidade. Para dar a ela a funcionalidade, você deve adicionar os controles filho e modificar o código em MyControl.xaml.cs ou MyControl.vb.

Incluirá a janela da ferramenta uma TextBox no qual você pode digitar um novo item de ToDo, um Button para adicionar o novo item à lista e um ListBox para exibir os itens na lista. A janela da ferramenta concluída deverá ser semelhante a figura a seguir:

Janela de ferramenta concluída

Para adicionar controles para a janela de ferramenta

  1. Exclua o botão, texto e controles StackPanel da grade.

    Dica

    Isso não exclui o manipulador de eventos button1_Click, que será reutilizada em uma etapa posterior.

  2. Da Todos os controles do WPF seção o caixa de ferramentas, arraste um tela controle à grade.

  3. Arraste um controle TextBox, um controle Button e um controle ListBox para a tela de desenho. Organizá-los como na figura acima.

  4. Selecione o botão. Defina seu conteúdo propriedade para Add.

  5. No painel de XAML, reconecte o manipulador de eventos do botão para o controle Button, adicionando um clique = "button1_Click" atributo. A linha resultante do XAML deve ter esta aparência:

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

    Salve seu trabalho.

Por padrão, o construtor de controle de usuário no arquivo MyControl.xaml.cs ou MyControl.xaml.vb sem parâmetros. No entanto, você pode personalizar o construtor para incluir parâmetros para que você pode salvar o pai para uso posterior.

Para personalizar o construtor

  1. Na página do designer, clique com o botão direito Exibir código.

  2. Substitua o construtor existente com o seguinte código:

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

    Isso permite que o construtor para levar um parâmetro do tipo MyToolWindow.

  3. Salve seu trabalho.

  4. Agora, adicione um parâmetro para o código que chama o construtor.

    Em Solution Explorer, abra MyToolWindow.cs ou MyToolWindow.vb.

  5. Localize a linha no construtor MyToolWindow que se parece com o código a seguir.

    Me.Content = New MyControl()
    
    base.Content = new MyControl();
    
  6. Altere a linha da seguinte maneira.

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

    Isso passa a instância da janela de ferramenta para o controle de usuário. (Isso é necessário em uma etapa posterior para criar o construtor da classe ToDoItem.)

Implementar um manipulador de comandos de Menu

Quando o projeto TodoList foi criado, ele incluía um manipulador padrão para o item de menu. O manipulador é no arquivo TodoListPackage. Agora, adicione código ao manipulador para exibir a janela de ferramenta. Você pode fazer isso em apenas algumas etapas porque TodoListPackage já contém uma função chamada ShowToolWindow.

Para implementar o manipulador de item de menu

  1. Abra TodoListPackage.cs ou TodoListPackage.vb. Observe que o manipulador de item de menu contém o código de exemplo a seguir.

    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. Remova tudo na função e substituí-lo com uma chamada para ShowToolWindow da seguinte maneira.

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

    Salve seu trabalho e, em seguida, pressione F5 para compilar o projeto e abri-lo na compilação experimental de Visual Studio. Testar se a janela da ferramenta for aberto clicando Gerenciador de ToDo sobre o Ferramentas menu.

    Feche a compilação experimental antes de continuar.

Criar uma página de opções

Você pode fornecer uma página no Opções caixa de diálogo para que os usuários podem alterar as configurações para a janela da ferramenta. A criação de uma página de opções requer uma classe que descreve as opções e uma entrada no arquivo TodoListPackage.cs ou TodoListPackage.vb.

Para criar uma página de opções

  1. Em Solution Explorer, o botão direito do mouse no projeto ToDoList, aponte para Adde, em seguida, clique em classe.

  2. No Add New Item caixa de diálogo, nomeie o arquivo ToolsOptions.cs, ou ToolsOptions.vb e, em seguida, clique em Add.

    Visual Studiocria uma classe nomeada ToolsOptions neste arquivo, mas você deve modificar o cabeçalho de classe, para que a classe é derivada de DialogPage.

    Adicionar o Microsoft.VisualStudio.Shell espaço para nome para o existente usando/importa diretivas, da seguinte maneira.

    Imports Microsoft.VisualStudio.Shell
    
    using Microsoft.VisualStudio.Shell;
    
  3. Modificar o ToolsOptions declaração para herdar da classe DialogPage.

    Inherits DialogPage
    
    class ToolsOptions : DialogPage
    
  4. A página de opções nesta explicação só fornecerá uma opção denominada DaysAhead. Para adicionar esta opção, adicione uma propriedade chamada DaysAhead para a classe ToolsOptions da seguinte maneira.

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

    Essa classe armazena uma única opção como um membro particular chamado _daysAhead. A classe, em seguida, fornece uma propriedade pública denominada DaysAhead para acessar a opção.

  5. Salve o arquivo.

Agora você deve tornar o projeto ciente desta página de opções para que ele será registrado corretamente e está disponível aos usuários.

Para tornar a página de opções disponíveis aos usuários

  1. Em Explorer soluções, abra TodoListPackage.cs ou TodoListPackage.vb.

  2. Localize a linha que contém o ProvideToolWindowAttribute de atributo e, em seguida, adicione um ProvideOptionPageAttribute atributo imediatamente após ele, como a seguir.

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

    Dica

    Você não precisará incluir a palavra 'Attribute' em declarações de atributo.

  3. Salve o arquivo.

    O primeiro parâmetro para o construtor de ProvideOptionPage é o tipo da classe ToolsOptions, que você criou anteriormente. O segundo parâmetro, "Tarefas", é o nome da categoria na Opções caixa de diálogo. O terceiro parâmetro, "Geral", é o nome da Subcategoria da Opções caixa de diálogo onde a página de opções estarão disponível. Os dois parâmetros são o recurso IDs para seqüências de caracteres; a primeira é o nome da categoria e o segundo é o nome da subcategoria. O parâmetro final define se essa página pode ser acessada por meio de automação.

    Quando a página de opções é acessada, ela deverá ser semelhante a figura a seguir.

    Página de opções

    Observe a categoria de tarefas pendentes e a subcategoria geral.

Disponibilizar dados para a janela Propriedades

Por princípios a seguir para um bom design orientado a objeto, você pode fazer uma classe chamada ToDoItem que armazena informações sobre os itens individuais na lista de tarefas pendentes.

Para disponibilizar os dados na janela Properties

  1. Em Solution Explorer, o botão direito do mouse no projeto ToDoList, aponte para Adde, em seguida, clique em classe.

  2. No Add New Item caixa de diálogo, nomeie o arquivo ToDoItem.cs ou ToDoItem.vbe, em seguida, clique em Add.

    Quando a janela da ferramenta está disponível para os usuários, os itens na caixa de listagem serão representados por instâncias de ToDoItem. Quando o usuário seleciona um desses itens na caixa de listagem, a Propriedades janela exibirá informações sobre o item.

    Para tornar dados disponíveis na Propriedades transformar os dados em propriedades públicas de uma classe de janela e, em seguida, documentá-las por meio de dois atributos especiais, descrição e categoria. A descrição é o texto que aparece na parte inferior do Propriedades janela. Categoria define onde a propriedade deverá aparecer quando o Propriedades janela é exibida no modo de exibição categorizado. Na figura a seguir, o Propriedades janela estiver no modo de exibição categorizado, o nome propriedade no Campos de tarefas categoria for selecionada e a descrição do nome propriedade é exibida na parte inferior da janela.

    Janela Propriedades

  3. Adicione os namespaces a seguir na parte superior do arquivo ToDoItem.cs ou ToDoItem.vb, depois que o existente usando/importa instruções.

    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. Começa a implementar a classe ToDoItem da seguinte maneira. Certifique-se de adicionar o public o modificador de acesso para a declaração 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();
            }
        }
    }
    

    Observe que esse código tem duas propriedades, Name e DueDate. Essas são as duas propriedades que serão exibidas no Propriedades janela, conforme mostrado na figura anterior. Cada propriedade é precedida por atributos de categoria e descrição, fornecem as informações para exibição na Propriedades janela. Examinar esses dois atributos para a propriedade Name; as seqüências devem corresponder da imagem.

  5. Adicione a seguinte função de construtor na parte superior da 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);
    }
    

    Em primeiro lugar, esse código declara um membro particular chamado _ parent, que corresponde ao controle de usuário que contém os controles TextBox, Button e ListBox que você criou anteriormente. O construtor utiliza o controle de usuário como um parâmetro, juntamente com uma seqüência que é o nome para este item afazer. As três primeiras linhas no construtor salvar o controle de usuário, o nome e a data e hora atuais.

    Você pode usar a data e hora atuais como base para habilitar a opção DaysAhead na página da opção que você criou anteriormente. Porque a data e hora atuais não são usados normalmente como uma data de vencimento, você pode Avançar a data atual pelo número de dias que são especificadas na página Opções. .

    O código declara uma variável local chamada daysAhead que é definida usando-se o valor na opção DaysAhead. A próxima linha obtém o pai do controle de usuário e a partir daí, o membro de pacote. (Isso é onde você pode usar o membro _ parent que você adicionou anteriormente à classe MyControl.xaml.cs).

    Se este membro do pacote não for nulo, um objeto é declarado que irá armazenar a instância de ToolsOptions. Para obter a instância, o código chama o membro GetAutomationObject do pacote e passa o nome da categoria e subcategoria como uma string delimitada por ponto única para Do.General. Os resultados são passados como um parâmetro de saída de volta para a variável obj.

    A variável obj será convertida para a classe ToolsOptions e salvo em uma variável chamada options. Se essa variável não for nula, o código obtém o DaysAhead membro e salva-o para o _daysAhead variável.

    O código, em seguida, avança o _duedate variável pelo número de dias com antecedência usando o AddDays método.

  6. Porque instâncias da ToDoItem classe será armazenada na caixa de listagem e entrará em contato com a caixa de listagem a ToString que esta classe herda de base da função Object da classe para recuperar a seqüência de caracteres a ser exibido para o item, você deverá sobrecarregar o ToString função.

    Adicione o seguinte código para ToDoItem.cs, após o construtor e antes do fim da 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. Abra MyControl.xaml.cs ou MyControl.xaml.vb.

  8. Adicionar métodos de stub para a classe MeuControle para o CheckForError e UpdateList métodos. Colocá-los após a ProcessDialogChar e antes do final do arquivo.

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

    O CheckForError método irá chamar um método que tem o mesmo nome no objeto pai, e esse método irá verificar se os erros tiverem ocorrido e tratá-las corretamente. O UpdateList método atualizará a caixa de listagem no controle pai; o método é chamado quando o Name e DueDate propriedades nesta alteração de classe. Você irá implementar esses métodos em uma etapa posterior.

Integrar a janela Propriedades

Agora escrever o código que gerencia a caixa de listagem, que será vinculada da Propriedades janela.

Você deve adicionar um identificador do botão que lê a caixa de texto, cria uma instância de ToDoItem e adiciona a ocorrência à caixa de listagem.

A integração com a janela Propriedades

  1. Alterne para o modo de design de MyControl.xaml, em seguida, clique duas vezes no controle Button

  2. Substituir o button1_Click a função de manipulador usando o código a seguir.

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

    Esse código cria uma nova instância de ToDoItem e passa a instância de controle de usuário como um parâmetro em conjunto com o texto inserido pelo usuário no controle TextBox. Em seguida, o código adiciona o item à caixa de listagem. (Caixa de listagem chamará o método ToString da instância de ToDoItem para recuperar a seqüência de caracteres na caixa de listagem). Em seguida, o código chama a função de TrackSelection, que você irá escrever em uma etapa posterior. Finalmente, o código verifica erros.

  3. Alterne para o modo de design de MyControl.xaml para adicionar o código que manipula a seleção de usuário de um novo item na caixa de listagem.

  4. Clique no controle ListBox. No Propriedades janela, clique duas vezes o evento SelectionChanged. Isso adiciona um stub para um manipulador SelectionChanged e atribui-lo para o evento.

  5. Preencher o manipulador SelectionChanged da seguinte maneira e uso de stubs no método chamadas.

    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. Salve seu trabalho. Você pode construir seu projeto e procure por erros de digitação.

  7. Agora, preencher a função de TrackSelection, que fornecerá integração com o Propriedades janela. Esta função é chamada quando o usuário adiciona um item à caixa de listagem ou clicar em um item na caixa de listagem.

    Agora que você tem uma classe que o Propriedades pode usar a janela, você pode integrar o Propriedades janela com a janela de ferramenta. Quando o usuário clica em um item na caixa de listagem na janela da ferramenta, o Propriedades janela deve ser atualizada. Da mesma forma, quando o usuário altera um item ToDo o Propriedades janela, o item associado deve ser atualizado.

    Dica

    Como alternativa, você pode gerar PropertyChanged eventos diretamente ao implementar a INotifyPropertyChanged interface.

    Coloque o código para a atualização do Propriedades janela na função TrackSelection. Isso irá vincular o objeto ToDoItem para o Propriedades janela; Você não precisará escrever qualquer código adicional para modificar o ToDoItem quando o usuário altera um valor na Propriedades janela. O Propriedades janela automaticamente chamará o set os assessores da propriedade para atualizar os valores. No entanto, você deve concluir o método UpdateList que você criou quando você escreveu o código para a classe ToDoItem.

  8. Adicione as seguintes declarações de namespace na parte superior do arquivo MyControl.xaml.cs ou MyControl.vb, depois que o existente usando/importa instruções.

    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. Implemente a função TrackSelection da seguinte maneira.

    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. Adicione o código a seguir logo após o final da função 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;
    }
    

    Este código chama a função de GetService. Essa função primeiro tenta obter o serviço do pai janela ferramenta chamando a função GetService. Se isso falhar, ele tentará obtê-lo a partir da função GetService do objeto. Porque a função GetService na janela da ferramenta pai não é pública, o código chama GetVsService. Você deve adicionar a função GetVsService.

  11. Abra MyToolWindow.cs ou MyToolWindow.vb. Adicione o seguinte código para o final da classe, pouco antes do final do arquivo.

    Friend Function GetVsService(ByVal service As Type) As Object 
        Return GetService(service)
    End Function
    
    internal object GetVsService(Type service)
    {
        return GetService(service);
    }
    
  12. Salve o arquivo.

    Na primeira vez que a função TrackSelection é executado, ele chama GetService para obter uma instância de Visual Studio shell. Em seguida, usa essa instância para obter um objeto para o Propriedades janela. Para obter o Propriedades objeto window, do início do código usando o GUID que representa o Propriedades janela. (A ferramenta windows os GUIDs são membros do ToolWindowGuids80 classe.) O código então chama a função FindToolWindow do shell, passando o GUID, para obter o Propriedades o objeto de janela. Isso salva-lo na variável de quadro, de modo que quando a função é chamada novamente, esse processo de obtenção de Propriedades janela não tem que ser repetido.

    Em seguida, o método chama o método Show da variável quadro para exibir o Propriedades janela.

    O próximo código reúne os itens selecionados na caixa de listagem. A caixa de listagem não está configurada para habilitar a seleção múltipla. Para passar o item selecionado para o Propriedades janela, você deve usar um recipiente. Portanto, o código reúne o item selecionado e coloca-o em uma ArrayList e em seguida, coloca esse ArrayList em um recipiente do tipo SelectionContainer.

    Em seguida, o código chama GetService para obter uma instância de ITrackSelection, que é o Visual Studio objetos na interface do usuário (UI) de objeto que controla o selecionado e exibe suas propriedades. Em seguida, o código diretamente chama o manipulador de eventos de OnSelectChange de ITrackSelection e passa a SelectionContainer que está mantendo o item selecionado. O resultado é que o Propriedades janela exibe as propriedades do item selecionado.

    Quando o usuário altera um objeto ToDoItem o Propriedades janela, o Propriedades janela chama automaticamente o set funções de acessor no objeto ToDoItem. Que atualiza o objeto, mas você ainda terá que atualizar a caixa de listagem.

  13. Em uma etapa anterior, você adicionou o código do set funções de assessor para chamar uma função UpdateList em MyControl.xaml.cs ou MyControl.xaml.vb. Agora, adicione o restante do código da função UpdateList.

  14. MyControl.xaml.cs ou MyControl.xaml.vb, implemente o método de UpdateList da seguinte maneira.

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

    Esse código determina qual item está selecionado e irá corresponder do ToDoItem que está sendo modificado. O código remove o item da caixa de listagem e, em seguida, re-inserts-lo. Isso atualiza a linha na caixa de listagem para o item. Em seguida, o código define a seleção de volta para o mesmo item.

  15. Salve seu trabalho.

Adicionar texto à janela de saída e itens à lista de tarefas

Para adicionar seqüências de caracteres para o Lista de tarefas e saída janela, você deve primeiro obter os objetos que se referem a essas duas janelas. Em seguida, você pode chamar métodos em objetos. Para o Lista de tarefas, você criar um novo objeto do tipo de tarefa e, em seguida, adicionar esse objeto de tarefa para o Lista de tarefas chamando o método Add. Para gravar o saída janela, você chamar o método GetPane para obter um objeto de painel e você chama o método OutputString do objeto de painel.

Para adicionar o texto para a janela de saída e a lista de tarefas

  1. Abra MyControl.xaml.cs ou MyControl.xaml.vb.

  2. Expanda o método button1_Click, inserindo o seguinte código antes da chamada para 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();
        }
    

    Esse código obtém o objeto para o saída janela. O objeto expõe uma interface IVsOutputWindow. O código obtém um objeto de IVsOutputWindowPane que inclui a função OutputString, que, por fim, grava o saída janela.

  3. Implemente o método CheckForErrors, da seguinte maneira.

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

    Este código chama o método de ReportError, que você criará em seguida, junto com outros métodos que ajudam a adicionar itens para o Lista de tarefas.

  4. Adicione o seguinte código para o final da classe, antes das duas chaves de fechamento.

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

    No início desse código é uma classe de TaskProvider especializada, denominada MyTaskProvider que inclui um GUID. Em seguida, é uma variável de membro desse tipo de classe nova, seguido por um método que cria a nova instância quando necessário.

    Em seguida são fornecidos dois métodos importantes, ClearError, que limpa os itens de tarefa existente, e ReportError, que adiciona itens a serem o Lista de tarefas.

    O método ReportError cria uma nova instância da tarefa, inicializa a instância e, em seguida, adiciona a instância para o Lista de tarefas. O novo Lista de tarefas entradas são visíveis apenas quando o usuário seleciona o item ToDo na lista suspensa na parte superior a Lista de tarefas. Duas últimas linhas do código, automaticamente, selecionem o item ToDo na lista drop-down e trazem novos itens de tarefa para o modo de exibição. O GUID é necessário quando a classe TaskProvider é herdada, porque o método SetActiveProvider requer um GUID como um parâmetro.

Experimentá-lo

Para testar a extensão

  1. Pressione CTRL + F5 para abrir a compilação experimental do Visual Studio.

  2. Na compilação experimental, sobre o Ferramentas menu, clique em Gerenciador de ToDo.

    Deve abrir a janela da ferramenta que você criou.

  3. Digite algo na caixa de texto e clique em Add.

    Você verá que o item é adicionado à caixa de listagem.

  4. Digite algo e, em seguida, clique em Add novamente.

    Como adicionar itens, a data inicial é definida como a data e hora atuais. Isso dispara um erro e também uma entrada na Lista de tarefas.

  5. Sobre o Exibir menu, clique em saída para abrir o saída janela.

    Observe que toda vez que você adiciona um item, será exibida uma mensagem no Lista de tarefas painel.

  6. Clique em um dos itens na caixa de listagem.

    O Propriedades janela exibe as duas propriedades para o item.

  7. Altere uma das propriedades e pressione ENTER.

    O item é atualizado na caixa de listagem.

O Que Mais Há

Esta explicação passo a passo, você criou uma janela de ferramenta que se integra a outra janela de ferramenta no Visual Studio. Visual Studiotem várias janelas de ferramenta que você pode trabalhar com e os GUIDs para essas podem ser encontrados na ToolWindowGuids classe. Você também criou uma classe que contém propriedades que o Propriedades janela pode acessar. Você forneceu acessador funções que o Propriedades janela utiliza. No set a função de assessor, chamado em seu próprio código para manipular as alterações efectuadas no Propriedades janela. Isso fornece um mecanismo de comunicação bidirecional. Finalmente, você aprendeu como adicionar itens para o Lista de tarefas, como trazer os itens para o modo de exibição e como adicionar texto para o saída janela.

Consulte também

Conceitos

Janela de saída (Visual Studio SDK)

Lista de tarefas

Outros recursos

Comandos, Menus e barras de ferramentas

Janelas de ferramentas

Janela Propriedades e páginas de propriedade