A menu is considered, or qualifies as, popup if, or because,
it can appear anywhere on the form as the programmer wishes. Such a menu is also
referred to as context-sensitive or contextual because its appearance and
behavior depend on where it displays on the form or on a particular control. The
person who creates the application decides if or where the contextual menu would
appear. Because this characteristic is up to the programmer, the same
application can display different types of popup menus depending on where the
user right-clicks. Here are examples:
The first difference between a main menu and a popup menu is
that a popup menu appears as one category or one list of items and not like a
group of categories of menus like a main menu. Secondly, while a main menu by
default is positioned on the top section of a form, a popup menu doesn't have a
specific location on the form.
Practical
Learning: Creating a Menu
|
|
- Start Microsoft Visual Basic
- Create a new Windows Application named AltairRealtors3b
- In the Solution Explorer, right-click Form1.vb and click Rename
- Type AltairRealtors.vb and press Enter
- From the Menus & Toolbars section of the Toolbox, click the MenuStrip
button
and click the form
- While the menu strip is still selected, in the Properties window, click
(Name), type MenuMain and press Enter
- On the form, click Type Here, type File and press Enter
- On the form, click File.
In the Properties window, click (Name) and type MenuFile
- On the form, click File and under it, click the Type Here box
- Type New Property and press Enter
- On the form, click File and click New Property.
In the Properties window, click (Name) and type MenuFileNewProperty
- On the form, click File and, under New Property, click the Type Here box
- Type Exit and press Enter
- On the form, click File and click Exit.
In the Properties window, click (Name) and type MenuFileExit
- Complete the design of the form as follows:
|
Control |
Text |
Name |
Other Properties |
MenuStrip |
|
|
|
|
Label |
|
Altair Realtors - Properties Listing |
|
Font: Times New Roman, 21.75pt,
style=Bold
ForeColor: MediumBlue |
ListView |
|
|
lvwProperties |
|
Columns |
(Name) |
Text |
TextAlign |
Width |
colPropertyNumber |
Prop # |
|
50 |
colPropertyType |
Property Type |
|
78 |
colAddress |
Address |
|
130 |
colCity |
City |
|
80 |
colState |
State |
|
40 |
colZIPCode |
ZIP Code |
Center |
58 |
colBedrooms |
Beds |
Right |
40 |
colBathrooms |
Baths |
Right |
40 |
colMarketValue |
Market Value |
Right |
75 |
|
- On the main menu, click Project -> Add Windows Form...
- Set the Name to RealEstateProperty and click Add
- Design the form as follows:
|
Control |
Text |
Name |
Other Properties |
Label |
|
Property #: |
|
|
TextBox |
|
|
txtPropertyNumber |
Modifiers: Public |
Label |
|
Property Type: |
|
|
ComboBox |
|
|
cbxPropertyTypes |
Modifiers: Public
Items:
Unknown
Single Family
Townhouse
Condominium |
Label |
|
Address: |
|
|
TextBox |
|
|
txtAddress |
Modifiers: Public |
Label |
|
City: |
|
|
TextBox |
|
|
txtCity |
Modifiers: Public |
Label |
|
State: |
|
|
ComboBox |
|
|
cbxStates |
Modifiers: Public
Items:
DC
MD
PA
VA
WV |
Label |
|
ZIP Code: |
|
|
TextBox |
|
|
txtZIPCode |
Modifiers: Public |
Label |
|
Bedrooms: |
|
|
TextBox |
|
0 |
txtBedrooms |
Modifiers: Public |
Label |
|
Bathrooms: |
|
|
TextBox |
|
1.0 |
txtBathrooms |
Modifiers: Public |
Label |
|
Market Value: |
|
|
TextBox |
|
0.00 |
txtMarketValue |
Modifiers: Public |
Button |
|
OK |
btnOK |
DialogResult: OK |
Button |
|
Cancel |
btnCancel |
DialogResult: Cancel |
|
Form |
FormBorderStyle: |
FixedDialog |
Text: |
Altair Realtors - Available Property |
StartPosition: |
CenterScreen |
AcceptButton: |
btnOK |
CancelButton: |
btnCancel |
MaximizeBox: |
False |
MinimizeBox: |
False |
ShowInTaskBar: |
False |
- Display the AltairRealtors form
- Right-click the form and click View Code
- In the Class Name combo box, select MenuFileNewProperty
- In the Method Name combo box, select Click and implement the event as
follows:
Private Sub MenuFileNewProperty_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles MenuFileNewProperty.Click
Dim rndNumber As Random
Dim number1 As Integer
Dim number2 As Integer
Dim PropertyNumber As String
Dim dlgProperty As RealEstateProperty
rndNumber = New Random(DateTime.Now.Millisecond)
number1 = rndNumber.Next(100, 999)
number2 = rndNumber.Next(100, 999)
PropertyNumber = number1 & number2
dlgProperty = New RealEstateProperty
dlgProperty.txtPropertyNumber.Text = PropertyNumber
dlgProperty.Text = "Altair Realtors - New Property"
If dlgProperty.ShowDialog() = Windows.Forms.DialogResult.OK Then
Dim strPropertyType As String = dlgProperty.cbxPropertyTypes.Text
Dim strAddress As String = dlgProperty.txtAddress.Text
Dim strCity As String = dlgProperty.txtCity.Text
Dim strState As String = dlgProperty.cbxStates.Text
Dim strZIPCde As String = dlgProperty.txtZIPCode.Text
Dim strBedrooms As String = dlgProperty.txtBedrooms.Text
Dim strBathrooms As String = dlgProperty.txtBathrooms.Text
Dim strMarketValue As String = dlgProperty.txtMarketValue.Text
Dim lviProperty As ListViewItem = _
New ListViewItem(dlgProperty.txtPropertyNumber.Text)
lviProperty.SubItems.Add(strPropertyType)
lviProperty.SubItems.Add(strAddress)
lviProperty.SubItems.Add(strCity)
lviProperty.SubItems.Add(strState)
lviProperty.SubItems.Add(strZIPCde)
lviProperty.SubItems.Add(strBedrooms)
lviProperty.SubItems.Add(strBathrooms)
lviProperty.SubItems.Add(strMarketValue)
lvwProperties.Items.Add(lviProperty)
End If
End Sub
|
- In the Class Name combo box, select MenuFileExit
- In the Method Name combo box, select Click and implement the event as
follows:
Private Sub MenuFileExit_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles MenuFileExit.Click
End
End Sub
|
- Execute the application
- To close the form, click File -> Exit
Creating a Contextual Menu
|
|
To support the creation and management of contextual menus,
the .NET Framework provides the ContextMenuStrip class. This class is
derived from ToolStripDropDownMenu, which itself is based on the
ToolStripDropDown class. The ToolStripDropDown class is derived from
ToolStrip.
To visually create a contextual menu, in the Menus &
Toolbars section of the Toolbox, click the ContextMenuStrip button
and
click the form. Once you have a ContextMenuStrip object, you can create
its menu items. To do this, as mentioned for the MenuStrip, you can click the
first Type Here line, type a string, press Enter, and continue creating the
other menu items in the same way.
Unlike a main menu, a popup menu provides a single list of
items. If you want different popup menus for your form, you have two options.
You can create various popup menus or programmatically change your single popup
menu in response to something or some action on your form.
To programmatically create a contextual menu, start by
declaring a handle to ContextMenuStrip. Here is an example:
Imports System.Drawing
Imports System.Windows.Forms
Module Exercise
Public Class Starter
Inherits Form
Private Contextual As ContextMenuStrip
Dim components As System.ComponentModel.Container
Public Sub New()
InitializeComponent()
End Sub
Public Sub InitializeComponent()
Contextual = New ContextMenuStrip
End Sub
End Class
Function Main() As Integer
Dim frmStart As Starter = New Starter
Application.Run(frmStart)
Return 0
End Function
End Module
To assist you with each item of a contextual menu,
ToolStrip, the ancestor to the ContextMenuStrip class, is equipped
with a property named Items. This property is of type
ToolStripItemCollection, which is a collection-based class. The
ToolStripItemCollection class implements the IList, the
ICollection, and the IEnumerable interfaces.
To create one or more menu items, you can use the various
techniques we reviewed for the main menu. Here are examples:
Imports System.Drawing
Imports System.Windows.Forms
Module Exercise
Public Class Starter
Inherits Form
Private MenuEditCut As ToolStripMenuItem
Private Contextual As ContextMenuStrip
Dim components As System.ComponentModel.Container
Public Sub New()
InitializeComponent()
End Sub
Public Sub InitializeComponent()
Contextual = New ContextMenuStrip
MenuEditCut = New ToolStripMenuItem("Cut")
Dim MenuEdit() As ToolStripMenuItem = _
{ _
New ToolStripMenuItem("Copy"), _
New ToolStripMenuItem("Paste") _
}
End Sub
End Class
Function Main() As Integer
Dim frmStart As Starter = New Starter
Application.Run(frmStart)
Return 0
End Function
End Module
After creating a menu item, to add it to the contextual
menu, you can call the ToolStripItemCollection.Add() method. To add an
array of items, you can call the create ToolStripItemCollection.AddRange()
method. Here are examples:
Public Sub InitializeComponent()
Contextual = New ContextMenuStrip
MenuEditCut = New ToolStripMenuItem("Cut")
Dim MenuEdit() As ToolStripMenuItem = _
{ _
New ToolStripMenuItem("Copy"), _
New ToolStripMenuItem("Paste") _
}
Contextual.Items.Add(MenuEditCut)
Contextual.Items.AddRange(MenuEdit)
End Sub
Practical Learning: Introducing Contextual Menus
|
|
- From the Menus & Toolbars section of the Toolbox, click ContextMenuStrip
and click the form
- While the context menu strip is still selected, in the Properties window
click (Name) and type MenuWithProperties
- Then click Items and click its ellipsis button
- Under the Select Item And Add To List combo box, make sure MenuItem is
selected and click Add
- On the right side, click Text and type Edit
- Click (Name) and type MenuEditProperty
- On the left side, click Add and, on the right side, change the
properties as follows:
Text: Delete
(Name): MenuDeleteProperty
- On the left side, click Add and, on the right side, change the
properties as follows:
Text: Clear
(Name): MenuClearProperties
- Click OK
- From the Menus & Toolbars section of the Toolbox, click ContextMenuStrip
and click the form
- While the context menu strip is still selected, in the Properties window
click (Name) and type MenuNoProperty
- On the form, under ContextMenuStrip, click Type Here
- Type New Property and press Enter
- On the form, under ContextMenuStrip, click New Property
- In the Properties window, click (Name), type MenuNewProperty and
press Enter
By default, a newly created contextual menu is attached
neither to the form nor to any control on it. In order to display a context
menu, you must assign its name to the control. To support this, Control,
the ancestor to all visual controls of the .NET Framework, is equipped, and
provides to its children, a property named ContextMenuStrip, which is of
type ContextMenuStrip.
To visually assign a contextual menu to a control during
design, click the control. In the Properties window, click the ContextMenuStrip
field, then click the arrow of its combo box, and select the menu. If you had
created more than one contextual menu, the combo box would show all of them and
you can choose the one you want to use as default.
To programmatically specify the contextual menu of a
control, assign a ContextMenuStrip object to its ContextMenuStrip
property. Here is an example:
Public Sub InitializeComponent()
Contextual = New ContextMenuStrip
MenuEditCut = New ToolStripMenuItem("Cut")
Dim MenuEdit() As ToolStripMenuItem = _
{ _
New ToolStripMenuItem("Copy"), _
New ToolStripMenuItem("Paste") _
}
Contextual.Items.Add(MenuEditCut)
Contextual.Items.AddRange(MenuEdit)
ContextMenuStrip = Contextual
End Sub
After assigning a
ContextMenuStrip object to a control, when you right-click (actually when
the user right-clicks) the control, the contextual menu would display. The above
code would produce:
Practical
Learning: Creating a Context Menu
|
|
- Right-click the form and click View Code
- Just under the Public Class AltairRealtors line, declare a ListViewItem
variable named itmSelected
Public Class AltairRealtors
Private itmSelected As ListViewItem
. . . No Change
|
- In the Class Name combo box, select (AltairRealtors Events)
- In the Method Name combo box, select Load and implement the event as
follows:
Private Sub AltairRealtors_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles Me.Load
itmSelected = New ListViewItem()
lvwProperties.ContextMenuStrip = MenuNoProperty
End Sub
|
- In the Class Name combo box, select lvwProperties
- In the Method Name combo box, select MouseDown and implement the event
as follows:
Private Sub lvwProperties_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles lvwProperties.MouseDown
If e.Button = Windows.Forms.MouseButtons.Right Then
If lvwProperties.SelectedItems.Count > 0 Then
itmSelected = lvwProperties.SelectedItems(0)
Else
itmSelected = Nothing
End If
End If
End Sub
|
- Save the file
In your application, you can create as many contextual menus
as you want. If you have different controls, each can have its own contextual
menu or many can share a contextual menu. Also, you can use different contextual
menus for a control and decide what menu to display when/why.
There is nothing particularly specific with writing code for
a popup menu item. You approach it exactly as if you were dealing with a menu
item of a main menu. You can write code for an item of a popup menu independent
of any other item of a main menu. If you want an item of a popup menu to respond
to the same request as an item of a main menu, you can write code for one of the
menu items (either the item on the main menu or the item on the popup menu) and
simply call its Click event in the event of the other menu item.
Practical
Learning: Using Various Contextual Menus
|
|
- In the Class Name combo box, select lvwProperties
- In the Method Name combo box, select ItemSelectionChanged and implement
the event as follows:
Private Sub lvwProperties_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles lvwProperties.MouseDown
If e.Button = Windows.Forms.MouseButtons.Right Then
If lvwProperties.SelectedItems.Count > 0 Then
itmSelected = lvwProperties.SelectedItems(0)
Else
itmSelected = Nothing
End If
End If
End Sub
|
- In the Class Name combo box, select MenuEditProperties
- In the Method Name combo box, select Click and implement the event as
follows:
Private Sub MenuEditProperty_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles MenuEditProperty.Click
' Prepare to open the AvailableProperties dialog box
Dim dlgProperty As RealEstateProperty = New RealEstateProperty
' Make sure an item, and only one, is selected
If (lvwProperties.SelectedItems.Count = 0) Or _
(lvwProperties.SelectedItems.Count > 1) Then
Exit Sub
End If
' Identify the item that is currently selected
Dim lviCurrent As ListViewItem = lvwProperties.SelectedItems(0)
' Display the ItemDetails dialog box with the item number
dlgProperty.txtPropertyNumber.Text = lviCurrent.Text
dlgProperty.cbxPropertyTypes.Text = lviCurrent.SubItems(1).Text
dlgProperty.txtAddress.Text = lviCurrent.SubItems(2).Text
dlgProperty.txtCity.Text = lviCurrent.SubItems(3).Text
dlgProperty.cbxStates.Text = lviCurrent.SubItems(4).Text
dlgProperty.txtZIPCode.Text = lviCurrent.SubItems(5).Text
dlgProperty.txtBedrooms.Text = lviCurrent.SubItems(6).Text
dlgProperty.txtBathrooms.Text = lviCurrent.SubItems(7).Text
dlgProperty.txtMarketValue.Text = lviCurrent.SubItems(8).Text
If dlgProperty.ShowDialog() = Windows.Forms.DialogResult.OK Then
lvwProperties.SelectedItems(0).Text = _
dlgProperty.txtPropertyNumber.Text
lvwProperties.SelectedItems(0).SubItems(1).Text = _
dlgProperty.cbxPropertyTypes.Text
lvwProperties.SelectedItems(0).SubItems(2).Text = _
dlgProperty.txtAddress.Text
lvwProperties.SelectedItems(0).SubItems(3).Text = _
dlgProperty.txtCity.Text
lvwProperties.SelectedItems(0).SubItems(4).Text = _
dlgProperty.cbxStates.Text
lvwProperties.SelectedItems(0).SubItems(5).Text = _
dlgProperty.txtZIPCode.Text
lvwProperties.SelectedItems(0).SubItems(6).Text = _
dlgProperty.txtBedrooms.Text
lvwProperties.SelectedItems(0).SubItems(7).Text = _
dlgProperty.txtBathrooms.Text
lvwProperties.SelectedItems(0).SubItems(8).Text = _
dlgProperty.txtMarketValue.Text
End If
End Sub
|
- In the Class Name combo box, select MenuDeleteProperty
- In the Method Name combo box, select Click and implement the event as
follows:
Private Sub MenuDeleteProperty_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles MenuDeleteProperty.Click
If lvwProperties.SelectedItems.Count = 0 Then Exit Sub
Dim Answer As MsgBoxResult
Answer = MsgBox("Are you sure you want " & _
"to delete that property?", _
MsgBoxStyle.YesNo Or MsgBoxStyle.Question, _
"Delete Property")
If Answer = MsgBoxResult.Yes Then
lvwProperties.SelectedItems(0).Remove()
End If
End Sub
|
- In the Class Name combo box, select MenuClearProperty
- In the Method Name combo box, select Click and implement the event as
follows:
Private Sub MenuClearProperties_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles MenuClearProperties.Click
Dim Answer As MsgBoxResult
Answer = MsgBox("Are you sure you want " & _
"to delete all properties?", _
MsgBoxStyle.YesNo Or MsgBoxStyle.Question, _
"Remove all Properties")
If Answer = MsgBoxResult.Yes Then
lvwProperties.Items.Clear()
End If
End Sub
|
- In the Class Name combo box, select MenuNewProperty
- In the Method Name combo box, select Click and implement the event as
follows:
Private Sub MenuNewProperty_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles MenuNewProperty.Click
MenuFileNewProperty_Click(sender, e)
End Sub
|
- Execute the application and test it
- Right-click an empty line of the list view to see the contextual menu
and click New Property
- Right-click the list view and click Edit
- Right-click a row on the form and click Delete
- Accept to delete the property
- Close the form and return to your programming environment
|
|