During our research that spread over a month and a half, we
could not find any GridView ContextMenu enabled! This is the first built-in
enabled GridView ContextMenu!
We have used the context menu developed by Dino Esposito that
was published in the MSDN magazine. A link to that article is listed below in
the resource section.
That context menu was developed mainly for ASP.NET 1.1. We
have created a new project in ASP.NET 2.0 and copied the same code with some
changes. In one change OnClickClick property has
been added to each context menu item so that developers can attach some client
side code that runs before posting back to the server.
The client side code, mainly the JavaScript used by the
context menu, is now included as a resource according to the techniques used in
ASP.NET 2.0.
The context menu is now an ASP.NET 2.0 project. It has been
integrated within each row in the extended GridView control, so that when you
right click on a row, you will be able to have access to the right-clicked row.
The extended GridView control now has a new property called RightClickRow that
returns the current row that has been right-clicked to show the context menu.
Related properties to this feature are:
·
ContextMenuID: The GridView is context
menu enabled when this property is set to the ID of a context menu placed on the
ASPX page.
·
RightClickedRow: This property returns
the GridViewRow where the right click was applied to show the context menu. Any
option you choose from the context menu will be applied on the current row
where you have applied a mouse right click.
Figure 3 shows a context menu when a mouse right click was
applied on a row.
Figure 3
The context menu popped up when a mouse right click was
applied on the row. The current context menu shows 3 different options.
Add a new Row: When clicked, a new
entry row will be shown in the footer of the GridView control. This is shown
in Figure 4.
Delete Row: Allows you to delete the
current right-clicked row.
Edit Row: Allows you to set the
current right-clicked row in the edit mode.
Figure 4 that shows the GridView control in Insert mode when
the “Add a new Row” option from the context menu was chosen.
Figure 4
Notice that the Context menu can be bound in several ways.
·
You can manually add new ContextMenuItem objects through the
ContextMenuItems property of the context menu.
·
You can gather data from a database, loop through them and
finally add them to the ContextMenuItems property of the context menu.
·
Also, you can load an XML file.
The following are the steps required to enable Context Menu
on the GridView control.
·
Add an instance of the ContextMenu control on the ASP.NET page.
·
Add an event handler for the items clicked inside the ContextMenu.
·
Load ContextMenu with ContextMenuItems.
Configure the GridView control’s ContextMenuID with the ID
of the context menu added.
You can start as follows:
Listing 5
<ctMenu:ContextMenu ID="ContextMenu1"
runat="server" BackColor="#99CCCC"
ForeColor="Maroon" OnItemCommand="ContextMenu1_ItemCommand"
RolloverColor="#009999" />
The above code listing shows a ContextMenu having an ID of
ContextMenu1 and a handler for the menu items which is the OnItemCommand. This
handler will be fired once the user chooses an option from the ContextMenu.
The event handler can be something like the following.
Listing 6
protected void ContextMenu1_ItemCommand(object sender, CommandEventArgs e)
{
// Use the RightClickedRow property which is a GridViewRow to know
// which row was right-clicked
int rowIndex = this.XGrid1.RightClickedRow.RowIndex;
switch (e.CommandName)
{
case "Add":
this.XGrid1.ChangeInsertMode(true);
break;
case "Edit":
this.XGrid1.EditIndex = rowIndex;
break;
case "Delete":
DeleteGridViewRow(rowIndex);
break;
default:
break;
}
}
In case the user chooses “Add a new Row,” then we are
setting the GridView in an insert mode using the built-in new method,
ChangeInsertMode. This flips the GridView between Insert and normal modes. To
be able to allow the GridView to insert new rows, you need to set up the form
controls used to gather data from users in the FooterTemplate of each Row.
In case the user chooses “Edit Row,” we are setting the
GridView’s EditIndex so that the currently right-clicked row is in now edit
mode.
When the user chooses “Delete Row,” we are calling a method
that handles deleting from the GridView.
As aforementioned, we need to set the ContextMenuID property
of the GridView to “ContextMenu1” in order to enable ContextMenu on the GridView.
A sample GridView is shown below.
Listing 7
<xGrid:xGrid ID="XGrid1"
runat="server" AllowPaging="True"
AutoGenerateColumns="False" DataKeyNames="CustomerID"
ContextMenuID="ContextMenu1">
<Columns>
<asp:TemplateField HeaderText="Manage Row">
<edititemtemplate>
<asp:LinkButton
text="Update" runat="server" id="lnkUpdate"
CommandName="Update" CommandArgument='<%
Bind("CustomerID") %>' />
<asp:LinkButton
text="Cancel" runat="server" id="lnkCancel"
CommandName="Cancel" />
</edititemtemplate>
<footertemplate>
<confirmControl:ConfirmLinkButton ID="lnkAdd" runat="server"
Text="Add" MessageText="Are you sure you want to add this
record?" OnClick="btnAdd_Click" />
<asp:LinkButton
id="lnkCancelAdd" runat="server" text="Cancel"
OnClick="btnCancel_Click" />
</footertemplate>
<itemtemplate>
<asp:LinkButton
id="lnkEdit" runat="server" CommandArgument='<%
Bind("CustomerID") %>' CommandName="Edit"
text="Edit" __designer:wfdid="w1"></asp:LinkButton>
<confirmControl:ConfirmLinkButton id="lnkDelete"
runat="server" CommandArgument='<% Bind("CustomerID")
%>' CommandName="Delete" MessageText="Are you sure you want
to delete this record?" Text="Delete"></confirmControl:ConfirmLinkButton>
</itemtemplate>
</asp:TemplateField></Columns>
An example on how to load the ContextMenu from an XML file
is shown in the listing below.
Listing 8
private void PopulateContextMenu()
{
XmlReaderSettings settings = new XmlReaderSettings();
string contextmenuxml = Path.Combine(Request.PhysicalApplicationPath,
"contextmenu.xml");
NameTable nameTable = new NameTable();
object contextMenuItem = nameTable.Add("contextmenuitem");
settings.NameTable = nameTable;
using(XmlReader reader = XmlReader.Create(contextmenuxml, settings))
{
while (reader.Read())
{
// Read a single ContextMenuItem
if ((reader.NodeType == XmlNodeType.Element) && (contextMenuItem.Equals
(reader.LocalName)))
{
XmlReader subTree = reader.ReadSubtree();
ContextMenuItem menuItem = new ContextMenuItem();
// Get contents of a single ContextMenuItem
while (subTree.Read())
{
if ((subTree.NodeType == XmlNodeType.Element) &&
(subTree.LocalName.Equals("text")))
menuItem.Text = subTree.ReadString();
if ((subTree.NodeType == XmlNodeType.Element) &&
(subTree.LocalName.Equals("commandname")))
menuItem.CommandName = subTree.ReadString();
if ((subTree.NodeType == XmlNodeType.Element) &&
(subTree.LocalName.Equals("tooltip")))
menuItem.Tooltip = subTree.ReadString();
if ((subTree.NodeType == XmlNodeType.Element) &&
(subTree.LocalName.Equals("onclientclick")))
menuItem.OnClientClick = subTree.ReadString();
}
// Add item to ContextMenu
this.ContextMenu1.ContextMenuItems.Add(menuItem);
}
}
}
}
The XML file used is as follows.
Listing 9
<?xml version="1.0" encoding="utf-8" ?>
<contextmenu>
<contextmenuitem>
<text>Add a new Row</text>
<commandname>Add</commandname>
<tooltip>Add a new Row</tooltip>
<onclientclick />
</contextmenuitem>
<contextmenuitem>
<text>Delete Row</text>
<commandname>Delete</commandname>
<tooltip>Delete Row</tooltip>
<onclientclick>return
__ConfirmMessage('Are you sure you want to delete this
row?');</onclientclick>
</contextmenuitem>
<contextmenuitem>
<text>Edit Row</text>
<commandname>Edit</commandname>
<tooltip>Edit Row</tooltip>
<onclientclick />
</contextmenuitem>
</contextmenu>
Each ContextMenuItem contains the following fields to set.
·
Text: The text to be displayed in the
ContextMenu.
·
CommandName: The name of the command to
process, examples are "Edit," "Delete," "Add," or
any other command name that you want to handle in the OnItemCommand event
handler.
·
Tooltip: A tooltip to show on a
ContextMenuItem.
·
OnClientClick: Any valid client side code
to run before posting back to the server.