Menus Menus são uma forma conveniente de agrupar comandos similares ou relacionados em um único lugar. A maioria dos usuários está familiarizada com o conceito das barras de menus e espera que menus padrões como Arquivo, Editar, e Ajuda, apareçam na sua aplicação. Mesmo o computador novato rapidamente aprende que ao clicar em um menu na barra de menus, será mostrado uma lista dropdown (que abre para baixo) de comandos. Os menus tornaram-se popular em aplicações Windows no final da década de 1980, seguindo o sucesso do computador Macintosh da Apple. Antes dos menus, os usuários tinham que lidar com uma grande variedade de interfaces oferecidas por aplicações desktop. As teclas de funções ainda encontradas no topo dos teclados foram desenvolvidas em parte, como padrão de forma de acesso de funções e comuns em uma aplicação, e em alguns programas chegavam a prover um modelo de plástico que era colocado sobre essas teclas do teclado para ajudar aos usuários a lembrar os comandos disponíveis. Talvez, devido a esses fatos, muitos desenvolvedores tomam a funcionalidade e popularidade dos menus como garantia e não perdem tempo suficiente desenhando uma interface usável e consistente, para suas aplicações. Enquanto os elementos gráficos como os menus, barras de ferramentas, e outras construções, fazem as aplicações muito mais amigáveis, isso não é desculpa para ignorar um bom desenho de interface e confiar que os consumidores sejam experts para fazerem uso efetivo da interface. Antes de adicionar menus a sua aplicação, nós deveríamos falar sobre os tipos de estruturas de menus e as classes que as suportam no framework Dot Net. A barra de menu tradicional, algumas vezes chamada de menu principal ou um menu ancorado, é um conjunto de menus mostrados horizontalmente pelo topo da maioria das aplicações. Os menus em uma típica barra de menus mostram um lista dropdown de comandos quando são ativados com o mouse ou pela tecla de acesso do teclado. A figura 1 mostra um exemplo de uma barra de menu cotendo os menus File, View e Help. O menu View está exposto, e um submenu do item de menu Image também está sendo mostrado. Outro tipo de menu é o menu de contexto, também conhecido como menu popup ou menu de atalho. Um menu de contexto é um menu que aparece em uma situação particular, ou contexto. Tipicamente, um menu de contexto contém um conjunto de comandos ou menus
relacionados a um elemento gráfico específico da aplicação. Esses menus aparecem por toda a parte no ambiente Windows ao se clicar com o botão direito do mouse.
Figura 1. Menu suspenso Menus de contexto no DotNet são associados tipicamente com controles específicos, e seus conteúdos podem mudar para refletir as condições do controle ou tipo de item selecionado dentro do controle. Observe que os itens do menu de contexto podem também conter submenus similares aos que aparecem na barra de menu. A figura 2 mostra um exemplo de um menu de contexto associado à janela principal da aplicação.
Figura 2. Um menu de contexto
A classe Menu Todos os menus no DotNet derivam da classe Menu. Essa classe provê as funcionalidades básicas para todos os menus, como acesso ao menu superior, caso exista, e a coleção de itens de submenu para um determinado menu. A classe Menu é uma classe abstrata, o que significa que você não pode instanciá-la. Observe a tabela a seguir que mostra que a propriedade Menu.MenuItems contém uma coleção de objetos de MenuItem. A classe Menu é uma classe base para todos os menus no framework DotNet. Essa classe abstrata é uma parte do namespace System.Windows.Forms, e é herdeira direta da classe System.ComponentModel.Component. Propriedades públicas Handle
IsParent MdiListItem
Obtém o objeto window do menu. Utilizado como um porta de saída para operações especiais não suportadas pelo framework. Diz se o menu contém algum objeto MenuItem Obtém o MenuItem, se existir algum, que mostrará a lista de forms
MenuItems
GetContextMenu Métodos públicos
GetMainMenu MergeMenu
Eventos públicos
Dispose (herdado Component)
filhos MDI abertos no momento na aplicação. Obtém o objeto MenuItemCollection que possui a lista dos objetos de MenuItem anexadas a esse menu, ou null se nenhum item estiver anexado. Retorna o objeto de Menu de contexto que contém esse menu, ou null. Retorna o objeto de Menu principal que contém esse menu, ou null. Mescla um objeto de menu com o menu atual Ocorre quando o componente é destruído, de como quando o método Dispose é chamado para o componente.
A hierarquia da classe Menu Antes de trabalharmos com tipos específicos de menus e exemplos, é interessante dar um passo atrás e conhecer a hierarquia de classe para a classe Menu. A hierarquia de classe é o conjunto de classes a partir do qual uma determinada classe deriva, e nos permite obter algumas indicações do propósito e das capacidades contidas na classe em estudo. A hierarquia de classe para a classe Menu é também interessante porque ela é bastante similar a maioria das hierarquias de classe dos controles Windows Forms. A figura 3 mostra que há três classes além da classe Menu nessa hierarquia.
O ancestral de todas as classes do framework DotNet. Parte do namespace System
Object
MarshalByRefObject
Component
Um objeto com identidade distribuída cujo estado só é válido no contexto onde ele foi criado. É parte do namespace System. Um objeto MarshalByRefObject que existe dentro de um container. Parte do namespace System.ComponentModel.
Uma classe abstrata base para todos os objetos de menu. Parte do namespace Menu System.Windows.Forms Figura 3. A hierarquia de classes da classe Menu O framework DotNet possui três classes derivadas da classe abstrata Menu para dar suporte a barras de menus, menus de contexto e os itens de menu que eles contém. A classe MainMenu representa um menu principal para uma aplicação. Objetos MainMenu contém uma coleção de objetos MenuItem que são mostrados na barra de menu. A classe ContextMenu representa um menu de contexto associado a um controle específico. Objetos ContextMenu também contém uma coleção de objetos MenuItem que são mostrados quando o menu aparece (popup). A classe MenuItem representa um item de menu que aparece dentro de outros menus. Uma instância (objeto) de MenuItem pode conter ou não uma coleção de objetos MenuItem que aparecem como submenu dela. Mesmo sendo possível ter uma infinidade de submenus, é uma boa idéia manter uma hierarquia limitada de submenus (dois a três níveis). Muitos níveis de submenu podem confundir os usuários.
A barra de Menu Uma nova aplicação usando uma barra de menu é mostrada na figura 4. As opções Load e Exit foram adicionadas ao menu File na barra de menu principal. Observe como essas opções estão separadas por uma pequena linha. Esse tipo de linha é chamado separador de menu. Também foi acrescentado um menu View que será discutido mais à
frente. Como é esperado, a barra de menu aparecerá em nosso código como um objeto do tipo MainMenu. Menus como o menu File são representados como objetos MenuItem contidos dentro do objeto MainMenu. As opções de menu abaixo do menu File também são objetos MenuItem. Isso inclui o separador de menu bem como as opções Load e Exit.
Figura 4. Menu na aplicação
Adicionando o menu principal (Main Menu) Para adicionar um menu a aplicação clique e arraste em um objeto MenuStrip da Caixa de Ferramentas (Toolbox) para dentro do seu form. Um objeto MenuStrip chamado menuStrip1 é adicionado ao seu formulário. Esse objeto é mostrado em uma nova área chamada Trilha do Componente, abaixo do formulário, onde objetos que não possuem uma presença física (visual) na janela. Tais objetos incluem timers, conexões com bancos de dados, e menus principais. Esse procedimento pode ser observado na figura 5 a seguir.
Figura 5. Criação de um menu strip Observando o código gerado no arquivo Form1.Designer.cs podemos observar que algumas mudanças foram feitas pelo Visual Studio para a inclusão do Menu Strip ao projeto. Na classe Form1 um novo atributo foi criado, o menuStrip1: private System.Windows.Forms.MenuStrip menuStrip1;
O método InitializeComponent, que inicializa os atributos e os anexa ao formulário também apresenta mudanças. Um objeto para esse atributo é criado usando a palavra-chave new. A palavra-chave this refere-se ao objeto corrente da classe Form1. this.menuStrip1 = new System.Windows.Forms.MenuStrip();
Algumas características do objeto menuStrip1 são configurados como localização, nome, tamanho, índice de tabulação: this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(292, 24); this.menuStrip1.TabIndex = 0; this.menuStrip1.Text = "menuStrip1";
Mais adiante, o objeto menuStrip é anexado ao form usando a coleção Controls (os controles contidos dentro do Form1) através do método add. Além disso, a propriedade Form.MainMenuStrip recebe o objeto menuStrip1. Essa propriedade configura ou obtém um objeto menuStrip para aparecer como barra de menu principal. this.Controls.Add(this.menuStrip1); this.MainMenuStrip = this.menuStrip1;
Adicionando opções ao menu Com o menuStrip em nosso form funcionando como uma barra de menus, podemos adicionar as opções que devem aparecer. Cada menu é criado usando a classe menuItem. Clique no menuStrip dentro do form, uma vaga será aberta para que você possa digitar o nome da opção de menu. Você também pode mover-se para as laterais para criar opções ou mover-se para baixo para criar sub-opções da opção atual. Veja como funciona na figura 6, a seguir:
Figura 6. Criação de opções de menu Agora a sua aplicação contém um menu File na barra de menus. No código fonte, um atributo do tipo ToolStripMenuItem (um item de menu) foi acrescentado na classe Form1. private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
O método InitializeComponent agora contém linhas adicionais para inicializar essa opção de menu e adicioná-la ao objeto menuStrip1. this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ... this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.fileToolStripMenuItem});
... this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20); this.fileToolStripMenuItem.Text = "&File";
A primeira linha cria a opção de menu. A segunda linha o coloca dentro da coleção de itens do menuStrip1. E as linhas subseqüentes configuram essa opção (seu nome, seu tamanho, e o seu texto).
Adicionando as sub-opções ao menu Para adicionar sub-opções ao menu, clique na opção, e move a seta direcional do teclado para baixo de forma a abrir lacuna para uma nova sub-opção de menu. Digite o nome da sub-opção (neste caso, digite &Load) e pressione Enter. O “&” serve para que a letra que o sucede fique sublinhada criando um atalho. Ou seja, quando o usuário abrir o menu e digitar “L” a sub-opção Load será chamada como se tivesse sido clicada. Pode-se também criar atalhos pelo teclado. Para isso clique na subopção desejada (novamente o Load) e na janelinha properties escolha a opção shortcut keys. Clique na célula à direita dessa opção e escolha a combinação de teclas de teclado que servirá de atalho para essa subopção de menu (por exemplo, CTRL + L). Continuando a montar o menu, crie mais uma lacuna abaixo de Load e digite “-“, o que fará um separador de menu. Finalmente crie mais uma lacuna “E&xit” (sair). Voltando à figura 4, é assim que o menu deve ficar.
Evento de click em um menu Um menu não é muito útil se você não puder fazer nada com ele. Por isso, é comum definirmos event handlers (tratadores de eventos) para os menus. Eventos em controles Windows Forms podem ser adicionados pela subseção de propriedades. Se você clicar no botão de Events (aquele com um ícone de um “relâmpago”, como pode ser visto na figura 7 a seguir), será mostrada uma lista de eventos para o controle desejado. Para escolher um evento para o controle desejado basta darmos duploclique na opção do evento. Isso nos levará a janela de código onde a
função (método) de tratamento do evento escolhido será criada e poderemos definir o corpo dessa função com a funcionalidade relativa ao evento escolhido do controle desejado. Suponhamos por exemplo que desejamos definir o que acontece ao clicarmos (evento click) no opção Exit (que é o controle a ser clicado) do menu File. Para isso, mostramos a visualização do form. Clicamos em File e logo em seguida em Exit. Vamos até a subseção properties, mostrada na figura 7, e clicamos no botão Events (o do “relâmpago”). Procuramos na lista de eventos o evento click e na célula à direita dele damos um duplo-clique.
Figura 7. Subseção properties e o botão Events Automaticamente a janela de código do form será aberta mostrando a função (método) de tratamento de evento do clique no botão de opção Exit do menu File. O código é mostrado abaixo: private void exitToolStripMenuItem_Click(object sender, EventArgs e) { }
Observe que o método aparece vazio para que possamos preenchê-lo com o código desejado para o evento escolhido do controle desejado. Nesse caso o evento escolhido é o clique e o controle é a opção Exit do menu File. Também convém observar que esse método já vem automaticamente
recebendo dois parâmetros. Parâmetros são informações que passamos para os métodos ou funções (nesse contexto funções e métodos são sinônimos) para que eles realizam o que for necessário. Os parâmetros podem ou não ser utilizados por nós dependendo das nossas necessidades. No caso acima os dois parâmetros fornecidos são dois objetos. O primeiro é o objeto sender do tipo object. Ele é uma referência para o controle que disparou o evento. Ou seja, ele é uma referência para a opção Exit do menu File. Se precisarmos fazer alguma coisa com essa opção de menu, quando ela for clicada, podemos utilizar essa referência a ela. O outro parâmetro que foi passado é o objeto e do tipo event. Esse objeto contém uma série de características e informações do evento que foi disparado. Neste caso, o evento click. Se precisarmos de informações de informações adicionais sobre o evento podemos utilizar esse objeto. Agora precisamos fazer o mais importante. Dar corpo ao método. Afinal o que acontece quando o usuário clica na opção Exit? A resposta é simples: a aplicação é fechada. Para fecharmos a aplicação basta fecharmos o form que dá acesso a aplicação. Como estamos codificando dentro do próprio form, não podemos utilizar seu nome já que ele é uma classe. Precisamos fechar o objeto form que existirá no momento em que a aplicação estiver rodando. Para isso utilizamos a palavra reservada this. Essa palavra permite que dentro de uma classe acessemos o objeto criado a partir dessa classe. Todo form tem um método chamado close() que permite fecharmos o form. Assim para terminarmos a aplicação basta fecharmos o form como mostra o código abaixo. private void exitToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); }
Pronto. Com isso estamos dizendo que quando o usuário clicar na opção Exit do menu File, o form será fechado, fechando conseqüentemente a aplicação.