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:
Em Visual Basic extensibilidade. O idioma padrão do projeto é Visual Basic.
Em C# extensibilidade. O idioma padrão do projeto é C#.
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
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.
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.
No Opções de comando de página, defina nome do comando para Gerenciador de Todo e ID do comando para cmdidTodoCommand.
No Janela Opções da ferramenta de página, defina nome da janela para Gerenciador de Todo e ID do comando para cmdidTodoTool.
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:
Para adicionar controles para a janela de ferramenta
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.
Da Todos os controles do WPF seção o caixa de ferramentas, arraste um tela controle à grade.
Arraste um controle TextBox, um controle Button e um controle ListBox para a tela de desenho. Organizá-los como na figura acima.
Selecione o botão. Defina seu conteúdo propriedade para Add.
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
Na página do designer, clique com o botão direito Exibir código.
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.
Salve seu trabalho.
Agora, adicione um parâmetro para o código que chama o construtor.
Em Solution Explorer, abra MyToolWindow.cs ou MyToolWindow.vb.
Localize a linha no construtor MyToolWindow que se parece com o código a seguir.
Me.Content = New MyControl()
base.Content = new MyControl();
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
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)); }
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
Em Solution Explorer, o botão direito do mouse no projeto ToDoList, aponte para Adde, em seguida, clique em classe.
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;
Modificar o ToolsOptions declaração para herdar da classe DialogPage.
Inherits DialogPage
class ToolsOptions : DialogPage
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.
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
Em Explorer soluções, abra TodoListPackage.cs ou TodoListPackage.vb.
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.
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.
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
Em Solution Explorer, o botão direito do mouse no projeto ToDoList, aponte para Adde, em seguida, clique em classe.
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.
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;
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.
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.
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(); }
Abra MyControl.xaml.cs ou MyControl.xaml.vb.
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
Alterne para o modo de design de MyControl.xaml, em seguida, clique duas vezes no controle Button
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.
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.
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.
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() { }
Salve seu trabalho. Você pode construir seu projeto e procure por erros de digitação.
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.
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;
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); } }
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.
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); }
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.
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.
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.
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
Abra MyControl.xaml.cs ou MyControl.xaml.vb.
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.
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.
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
Pressione CTRL + F5 para abrir a compilação experimental do Visual Studio.
Na compilação experimental, sobre o Ferramentas menu, clique em Gerenciador de ToDo.
Deve abrir a janela da ferramenta que você criou.
Digite algo na caixa de texto e clique em Add.
Você verá que o item é adicionado à caixa de listagem.
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.
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.
Clique em um dos itens na caixa de listagem.
O Propriedades janela exibe as duas propriedades para o item.
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)