VB.NET - Criando menus em tempo de execução II
Estou voltando a este assunto abordado no artigo - VB.NET - Criando menus em tempo de execução - para atualizar e expandir o conceito de criar menus em tempo de execução no VB.
Neste artigo não vou usar o VS.NET vou usar o SharpDevelop e mostrar também como você pode obter o mesmo resultado usando a linha de comando.
Requisitos para testar o código deste artigo:
Podemos criar menus e menus contexto diretamente via código e é isto que vou mostrar como fazer neste artigo. Os passos essenciais para atingir este objetivo são:
Abaixo temos o código que cria um Menu com um item principal com alguns subitens:
Imports System Imports System.Drawing Imports System.Windows.Forms Namespace menuVB2 module modMain <STAThreadAttribute( )> Public Sub Main( ) System.Threading.Thread.CurrentThread.ApartmentState = System.Threading.ApartmentState.STA Application.Run(New Form1( )) End Sub End Module Public Class Form1 Inherits Form ' faz referência a label1 para exibir o texto Private WithEvents Label1 As New Label( ) ' Estes membros armazenam as propriedades originais de cor e fonte do controle label1 Private origFont As Font Private origForeColor As Color Private origBackColor As Color ' Estes membros manipulam os objetos MainMenu e ContextMenu. Private WithEvents MainMenu1 As New MainMenu( ) Private WithEvents ContextMenu1 As New ContextMenu( ) ' Estes membros tratam os objetos MenuItem Private WithEvents mnuFormat As New MenuItem( ) Private WithEvents mnuFormatFont As New MenuItem( ) Private WithEvents mnuFormatForeColor As New MenuItem( ) Private WithEvents mnuFormatBackColor As New MenuItem( ) Private mnuSeparator As New MenuItem( ) Private WithEvents mnuFormatReset As New MenuItem( ) Public Sub New( ) 'chama o construtor da classe pai (Forms) MyBase.New( ) ' Define o menu Formatar mnuFormat.Text = "F&ormatar" mnuFormatFont.Text = "&Fonte..." mnuFormatForeColor.Text = "F&oreColor..." mnuFormatBackColor.Text = "&BackColor..." mnuSeparator.Text = "-" mnuFormatReset.Text = "&Limpar" mnuFormat.MenuItems.AddRange(New MenuItem( ) {mnuFormatFont, _ mnuFormatForeColor, mnuFormatBackColor, mnuSeparator,mnuFormatReset}) ' Vincula o menu Formatar ao menu principal e vincula o menu principal ao formulário MainMenu1.MenuItems.Add(mnuFormat) Menu = MainMenu1 ' Faz um Clone do menu Formatar, vincula o clone ao menu de contexto e vincula o menu de contexto ao controle label ContextMenu1.MenuItems.Add(mnuFormat.CloneMenu( )) Label1.ContextMenu = ContextMenu1 ' Define as propriedades relacionadas do formulário e da label AutoScaleBaseSize = New Size(5, 13) ClientSize = New Size(312, 81) Controls.Add(Label1) Menu = MainMenu1 Name = "Form1" Text = "Criando Menus em tempo de execução" Label1.Text = "Testando Menu" Label1.AutoSize = True ' Salva as propriedades fonte e cor original do controle label origFont = Label1.Font origForeColor = Label1.ForeColor origBackColor = Label1.BackColor End Sub ' Tratamento do evento Click para Font Private Sub mnuFormatFont_Click( ByVal sender As Object, ByVal e As EventArgs ) Handles mnuFormatFont.Click Dim dlg As New FontDialog( ) dlg.Font = Label1.Font If dlg.ShowDialog = DialogResult.OK Then Label1.Font = dlg.Font End If dlg.Dispose( ) End Sub ' Tratamento do evento Click para ForeColor Private Sub mnuFormatForeColor_Click( ByVal sender As Object, ByVal e As EventArgs) Handles mnuFormatForeColor.Click Dim dlg As New ColorDialog( ) dlg.Color = Label1.ForeColor If dlg.ShowDialog = DialogResult.OK Then Label1.ForeColor = dlg.Color End If dlg.Dispose( ) End Sub ' Tratamento do evento Click para BackColor Private Sub mnuFormatBackColor_Click( ByVal sender As Object, ByVal e As EventArgs ) Handles mnuFormatBackColor.Click Dim dlg As New ColorDialog( ) dlg.Color = Label1.BackColor If dlg.ShowDialog = DialogResult.OK Then Label1.BackColor = dlg.Color End If dlg.Dispose( ) End Sub |
Compilando e Executando o código acima no SharpDevelop temos o resultado exibido nas figuras abaixo:
O menu | O menu de contexto |
A interação do usuário com os Menus e seus itens disparam eventos. O evento mais comum da classe MenuItem é o evento Click que dispara quando um usuário clica um item do menu. Abaixo temos um trecho de código que faz o tratamento para um suposto item de menu Sair que encerra a aplicação.
Private Sub mnuSair_Click( ByVal sender As Object,
ByVal e As EventArgs ) Handles mnuSair.Click Me.Close( ) End Sub |
Alguns do principais eventos da classe MeuItem são :
Click | Disparado quando um item do menu é selecionado via mouse ou via atalho |
Dispose | Disparado quando o método Dispose do objeto MenuItem é invocado. |
DrawItem | Disparado quando um item do menu precisa ser desenhado, quando a propriedade OwnerDraw for True |
Popup | Disparado quando o sub-menu esta prestes a ser exibido quando um item do menu possui sub-itens associados a ele |
Select | Disparado quando o usuário põe o mouse sobre o item do menu ou quando o navega pelo item usando o teclado. |
MeasureItem | Disparado antes do evento DrawItem quando a propriedade OwnerDraw do objeto MenuItem for True |
Index | O índice de um item do menu dentro do menu pai. |
State | Indica o estado do item do menu. O tipo é DrawItemState. |
Graphics | A superfície gráfica onde o item vai ser desenhado |
Clonando Menus
As vezes os itens de Meus e seus subitens precisam aparecer em mais de um local e não somente no Menu. Um exemplo comum é o caso de uma aplicação que possui menus de contexto contendo algumas das mesmas funcionalidades que o menu da aplicação.
Os objetos MenuItem não funcionam corretamente quando são atribuídos a mais de um menu. Uma solução simples para o problema é usar o método CloneMenu que retorna um novo objeto MenuItem cujas propriedades são definidas da mesma forma que o objeto MenuItem. Se o MenuItem original possuir submenus, ele será clonado também.
Se você quiser compilar o código acima usando a linha de comando fique a vontade , abaixo esta o comando , apenas substitua o nome_do_arquivo pelo nome que você salvou o arquivo com o código cima.
vbc nome_do_arquivo.vb /r:System.dll,System.Drawing.dll,System.Windows.Forms.dll /t:winexe
Nota: Para saber mais leia o artigo : VB.NET - O DOS morreu . Viva o DOS !
O evento CloneMenu detecta os manipuladores de eventos que estão definidos para MenuItems os clona e automaticamente registra os eventos manipuladores com eventos correspondentes para os novo objetos MenuItem criados.
Para exibir as opções de fonte e de cores dos itens do Menu eu estou usando as Caixas de Diálogo : ColorDialog() e FontDialog(). Além destas caixas temos também as caixas de diálogo Open e Save. O código para abrir e exibir as caixas é padrão , veja abaixo :
Dim dlg As New FontDialog( ) dlg.Font = Label1.Font If dlg.ShowDialog = DialogResult.OK Then Label1.Font = dlg.Font End If dlg.Dispose( ) End Sub |
- instanciamos um
objeto dlg do tipo FontDialog (ColorDialog, etc) - atribuímos a Fonte usada a propriedade Font do controle |
Até o próximo artigo VB.NET
José Carlos Macoratti