| |
 |
Popup Menus
This topic shows how to customize a Data Grid's built-in popup menus, override the default menu item actions, and use events to create custom popup menus.
Note
This topic does not cover in-place editors' menu items.
In this topic:

Built-In Context Menus
The Data Grid's Grid Views and Banded Grid Views have five built-in context menus.
-
Column Header Menu (right-click a Column Header)

Example:
C# |
gridView1.OptionsMenu.ShowAutoFilterRowItem = false;
gridView1.OptionsMenu.ShowConditionalFormattingItem = true;
gridView1.OptionsMenu.ShowGroupSummaryEditorItem = true;
|
VB |
gridView1.OptionsMenu.ShowAutoFilterRowItem = False
gridView1.OptionsMenu.ShowConditionalFormattingItem = True
gridView1.OptionsMenu.ShowGroupSummaryEditorItem = True
|
-
Group Panel Menu (right-click the Group Panel)

C# |
gridView1.OptionsMenu.ShowSplitItem = true;
|
VB |
gridView1.OptionsMenu.ShowSplitItem = True
|
-
Summary Menu (right-click the total summary footer and group summary footers)

C# |
gridView1.OptionsMenu.ShowAddNewSummaryItem = DevExpress.Utils.DefaultBoolean.False;
|
VB |
gridView1.OptionsMenu.ShowAddNewSummaryItem = DevExpress.Utils.DefaultBoolean.False
|
-
Auto-Filter Row Menu (click a condition selector in the Auto-Filter Row)

C# |
gridView1.OptionsFilter.AllowAutoFilterConditionChange = DevExpress.Utils.DefaultBoolean.False;
|
VB |
gridView1.OptionsFilter.AllowAutoFilterConditionChange = DevExpress.Utils.DefaultBoolean.False
|
-
Row Menu (right-click a Data Row or Group Row)
This menu is initially empty and thus is not displayed. Handle the GridView.PopupMenuShowing event to add custom commands to the row menu. See the Add Custom Items to Built-In Menus section for an example.
The properties the Views provide can affect the availability of certain items in these menus. For instance, when you disable the GridOptionsCustomization.AllowSort option, the "Sort Ascending" and "Sort Descending" items are automatically deactivated in the Column Header Menu.
Not all menu items can be hidden using the View's properties. To control the visibility of any menu item, use the GridView.PopupMenuShowing event as described below.

Customize, Hide and Disable Default Menu Items
To customize menu items (for example, change their captions and visibility), handle the GridView.PopupMenuShowing event. This event fires each time the menu is invoked.
The event's e.Menu parameter allows you to get the displayed menu. You can iterate through the e.Menu.Items collection or call the e.Menu.Find and e.Menu.FindAll methods to access individual menu items.
To hide or remove certain menu items, use the e.Menu.Hide and e.Menu.Remove methods. These methods accept menu item identifiers as parameters. Refer to PopupMenuShowingEventArgs.Menu for information about menu item identification.

Example
The following code customizes the existing commands in the Data Grid's Column Header Menu by handling the GridView.PopupMenuShowing event:
-
Captions of the "Sort Ascending" and "Sort Descending" commands are replaced with custom strings;
-
A few commands are hidden;
-
Two "Best Fit" commands are disabled.

C# |
using DevExpress.Utils.Menu;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Localization;
using DevExpress.XtraGrid.Views.Grid;
private void gridView1_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e) {
if(e.MenuType == GridMenuType.Column) {
string sortAsc = "A to Z";
string sortDesc = "Z to A";
if (e.HitInfo.Column.ColumnType == typeof(DateTime)) {
sortAsc = "Old to New";
sortDesc = "New to Old";
}
DXMenuItem itemAsc = e.Menu.Find(GridStringId.MenuColumnSortAscending);
if (itemAsc != null)
itemAsc.Caption = sortAsc;
DXMenuItem itemDesc = e.Menu.Find(GridStringId.MenuColumnSortDescending);
if (itemDesc != null)
itemDesc.Caption = sortDesc;
e.Menu.Hide(GridStringId.MenuFooterHide);
e.Menu.Hide(GridStringId.MenuColumnFilterEditor);
e.Menu.Hide(GridStringId.MenuColumnFindFilterShow);
e.Menu.Hide(GridStringId.MenuColumnFindFilterHide);
e.Menu.Hide(GridStringId.MenuColumnAutoFilterRowHide);
e.Menu.Hide(GridStringId.MenuColumnAutoFilterRowShow);
DXMenuItem itemBestFit = e.Menu.Find(GridStringId.MenuColumnBestFit);
if (itemBestFit != null)
itemBestFit.Enabled = false;
DXMenuItem itemBestFitAll = e.Menu.Find(GridStringId.MenuColumnBestFitAllColumns);
if (itemBestFitAll != null)
itemBestFitAll.Enabled = false;
}
}
|
VB |
Imports DevExpress.Utils.Menu
Imports DevExpress.XtraEditors
Imports DevExpress.XtraGrid.Localization
Imports DevExpress.XtraGrid.Views.Grid
Private Sub gridView1_PopupMenuShowing(ByVal sender As Object, ByVal e As PopupMenuShowingEventArgs) Handles GridView1.PopupMenuShowing
If e.MenuType = GridMenuType.Column Then
Dim sortAsc As String = "A to Z"
Dim sortDesc As String = "Z to A"
If e.HitInfo.Column.ColumnType = GetType(DateTime) Then
sortAsc = "Old to New"
sortDesc = "New to Old"
End If
Dim itemAsc As DXMenuItem = e.Menu.Find(GridStringId.MenuColumnSortAscending)
If itemAsc IsNot Nothing Then itemAsc.Caption = sortAsc
Dim itemDesc As DXMenuItem = e.Menu.Find(GridStringId.MenuColumnSortDescending)
If itemDesc IsNot Nothing Then itemDesc.Caption = sortDesc
e.Menu.Hide(GridStringId.MenuFooterHide)
e.Menu.Hide(GridStringId.MenuColumnFilterEditor)
e.Menu.Hide(GridStringId.MenuColumnFindFilterShow)
e.Menu.Hide(GridStringId.MenuColumnFindFilterHide)
e.Menu.Hide(GridStringId.MenuColumnAutoFilterRowHide)
e.Menu.Hide(GridStringId.MenuColumnAutoFilterRowShow)
Dim itemBestFit As DXMenuItem = e.Menu.Find(GridStringId.MenuColumnBestFit)
If itemBestFit IsNot Nothing Then itemBestFit.Enabled = False
Dim itemBestFitAll As DXMenuItem = e.Menu.Find(GridStringId.MenuColumnBestFitAllColumns)
If itemBestFitAll IsNot Nothing Then itemBestFitAll.Enabled = False
End If
End Sub
|

Add Custom Items to Built-In Menus
Handle the GridView.PopupMenuShowing event and add custom items to the event's e.Menu.Items parameter. You can use the following objects as custom items:

Example
The following example shows how to use the GridView.PopupMenuShowing event to create a custom menu in the Data Grid control. The created menu is displayed when you right-click within a data row or group row. It contains a 'Rows' submenu with a single "Delete this row" regular button, and a 'Cell Merging' check button.

A click on the 'Delete this row' button invokes the ColumnView.DeleteRow method. The 'Cell Merging' check button toggles the GridOptionsView.AllowCellMerge option.
C# |
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.Utils.Menu;
using DevExpress.XtraEditors;
private void gridView1_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e) {
GridView view = sender as GridView;
if (e.MenuType == DevExpress.XtraGrid.Views.Grid.GridMenuType.Row) {
int rowHandle = e.HitInfo.RowHandle;
e.Menu.Items.Clear();
e.Menu.Items.Add(CreateSubMenuRows(view, rowHandle));
DXMenuItem item = CreateMenuItemCellMerging(view, rowHandle);
item.BeginGroup = true;
e.Menu.Items.Add(item);
}
}
DXMenuItem CreateSubMenuRows(GridView view, int rowHandle) {
DXSubMenuItem subMenu = new DXSubMenuItem("Rows");
string deleteRowsCommandCaption;
if (view.IsGroupRow(rowHandle))
deleteRowsCommandCaption = "&Delete rows in this group";
else
deleteRowsCommandCaption = "&Delete this row";
DXMenuItem menuItemDeleteRow = new DXMenuItem(deleteRowsCommandCaption, new EventHandler(OnDeleteRowClick), imageCollection1.Images[0]);
menuItemDeleteRow.Tag = new RowInfo(view, rowHandle);
menuItemDeleteRow.Enabled = view.IsDataRow(rowHandle) || view.IsGroupRow(rowHandle);
subMenu.Items.Add(menuItemDeleteRow);
return subMenu;
}
DXMenuCheckItem CreateMenuItemCellMerging(GridView view, int rowHandle) {
DXMenuCheckItem checkItem = new DXMenuCheckItem("Cell &Merging",
view.OptionsView.AllowCellMerge, null, new EventHandler(OnCellMergingClick));
checkItem.Tag = new RowInfo(view, rowHandle);
checkItem.ImageOptions.Image = imageCollection1.Images[1];
return checkItem;
}
void OnDeleteRowClick(object sender, EventArgs e) {
DXMenuItem menuItem = sender as DXMenuItem;
RowInfo ri = menuItem.Tag as RowInfo;
if (ri != null) {
string message = menuItem.Caption.Replace("&", "");
if (XtraMessageBox.Show(message + " ?", "Confirm operation", MessageBoxButtons.YesNo) != DialogResult.Yes)
return;
ri.View.DeleteRow(ri.RowHandle);
}
}
void OnCellMergingClick(object sender, EventArgs e) {
DXMenuCheckItem item = sender as DXMenuCheckItem;
RowInfo info = item.Tag as RowInfo;
info.View.OptionsView.AllowCellMerge = item.Checked;
}
class RowInfo {
public RowInfo(GridView view, int rowHandle) {
this.RowHandle = rowHandle;
this.View = view;
}
public GridView View;
public int RowHandle;
}
|
VB |
Imports DevExpress.Utils.Menu
Imports DevExpress.XtraEditors
Imports DevExpress.XtraGrid.Views.Grid
Private Sub GridView1_PopupMenuShowing(sender As Object, e As PopupMenuShowingEventArgs) Handles GridView1.PopupMenuShowing
Dim view As GridView = TryCast(sender, GridView)
If e.MenuType = GridMenuType.Row Then
Dim rowHandle As Integer = e.HitInfo.RowHandle
e.Menu.Items.Clear()
e.Menu.Items.Add(CreateSubMenuRows(view, rowHandle))
Dim item As DXMenuItem = CreateMenuItemCellMerging(view, rowHandle)
item.BeginGroup = True
e.Menu.Items.Add(item)
End If
End Sub
Private Function CreateSubMenuRows(ByVal view As GridView, ByVal rowHandle As Integer) As DXMenuItem
Dim subMenu As DXSubMenuItem = New DXSubMenuItem("Rows")
Dim deleteRowsCommandCaption As String
If view.IsGroupRow(rowHandle) Then
deleteRowsCommandCaption = "&Delete rows in this group"
Else
deleteRowsCommandCaption = "&Delete this row"
End If
Dim menuItemDeleteRow As DXMenuItem = New DXMenuItem(deleteRowsCommandCaption, New EventHandler(AddressOf OnDeleteRowClick), ImageCollection1.Images(0))
menuItemDeleteRow.Tag = New RowInfo(view, rowHandle)
menuItemDeleteRow.Enabled = view.IsDataRow(rowHandle) OrElse view.IsGroupRow(rowHandle)
subMenu.Items.Add(menuItemDeleteRow)
Return subMenu
End Function
Private Function CreateMenuItemCellMerging(ByVal view As GridView, ByVal rowHandle As Integer) As DXMenuCheckItem
Dim checkItem As DXMenuCheckItem = New DXMenuCheckItem("Cell &Merging", view.OptionsView.AllowCellMerge, Nothing, New EventHandler(AddressOf OnCellMergingClick))
checkItem.Tag = New RowInfo(view, rowHandle)
checkItem.ImageOptions.Image = ImageCollection1.Images(1)
Return checkItem
End Function
Private Sub OnDeleteRowClick(ByVal sender As Object, ByVal e As EventArgs)
Dim menuItem As DXMenuItem = TryCast(sender, DXMenuItem)
Dim ri As RowInfo = TryCast(menuItem.Tag, RowInfo)
If ri IsNot Nothing Then
Dim message As String = menuItem.Caption.Replace("&", "")
If XtraMessageBox.Show(message & " ?", "Confirm operation", MessageBoxButtons.YesNo) <> DialogResult.Yes Then Return
ri.View.DeleteRow(ri.RowHandle)
End If
End Sub
Private Sub OnCellMergingClick(ByVal sender As Object, ByVal e As EventArgs)
Dim item As DXMenuCheckItem = TryCast(sender, DXMenuCheckItem)
Dim info As RowInfo = TryCast(item.Tag, RowInfo)
info.View.OptionsView.AllowCellMerge = item.Checked
End Sub
Class RowInfo
Public Sub New(ByVal view As GridView, ByVal rowHandle As Integer)
Me.RowHandle = rowHandle
Me.View = view
End Sub
Public View As GridView
Public RowHandle As Integer
End Class
|

Example
The following sample code handles the GridView.PopupMenuShowing event to customize the Column Header Context Menu before it is displayed. The code clears default menu items and adds a new command that locks a clicked column's position.

C# |
using DevExpress.XtraGrid.Menu;
using DevExpress.Utils.Menu;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
private void bandedGridView1_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e) {
if(e.MenuType == GridMenuType.Column) {
GridViewColumnMenu menu = e.Menu as GridViewColumnMenu;
menu.Items.Clear();
if(menu.Column != null) {
menu.Items.Add(CreateCheckItem("Lock this column", menu.Column, null));
}
}
}
DXMenuCheckItem CreateCheckItem(string caption, GridColumn column, Image image) {
DXMenuCheckItem item = new DXMenuCheckItem(caption,
!column.OptionsColumn.AllowMove, image, new EventHandler(OnCanMoveItemClick));
item.Tag = new MenuColumnInfo(column);
return item;
}
void OnCanMoveItemClick(object sender, EventArgs e) {
DXMenuCheckItem item = sender as DXMenuCheckItem;
MenuColumnInfo info = item.Tag as MenuColumnInfo;
if(info == null) return;
info.Column.OptionsColumn.AllowMove = !item.Checked;
}
class MenuColumnInfo {
public MenuColumnInfo(GridColumn column) {
this.Column = column;
}
public GridColumn Column;
}
|
VB |
Imports DevExpress.XtraGrid.Menu
Imports DevExpress.Utils.Menu
Imports DevExpress.XtraGrid.Columns
Imports DevExpress.XtraGrid.Views.Grid
Private Sub bandedGridView1_PopupMenuShowing(ByVal sender As Object, ByVal e As PopupMenuShowingEventArgs)
If e.MenuType = GridMenuType.Column Then
Dim menu As GridViewColumnMenu = TryCast(e.Menu, GridViewColumnMenu)
menu.Items.Clear()
If menu.Column IsNot Nothing Then
menu.Items.Add(CreateCheckItem("Lock this column", menu.Column, Nothing))
End If
End If
End Sub
Private Function CreateCheckItem(ByVal caption As String, ByVal column As GridColumn, ByVal image As Image) As DXMenuCheckItem
Dim item As New DXMenuCheckItem(caption, (Not column.OptionsColumn.AllowMove), image, New EventHandler(AddressOf OnCanMoveItemClick))
item.Tag = New MenuColumnInfo(column)
Return item
End Function
Private Sub OnCanMoveItemClick(ByVal sender As Object, ByVal e As EventArgs)
Dim item As DXMenuCheckItem = TryCast(sender, DXMenuCheckItem)
Dim info As MenuColumnInfo = TryCast(item.Tag, MenuColumnInfo)
If info Is Nothing Then
Return
End If
info.Column.OptionsColumn.AllowMove = Not item.Checked
End Sub
Friend Class MenuColumnInfo
Public Sub New(ByVal column As GridColumn)
Me.Column = column
End Sub
Public Column As GridColumn
End Class
|

Change Menu Items' Default Behavior
A click on a menu item in the built-in context menus raises the GridView.GridMenuItemClick event. After your event handler is complete, the grid performs the menu item's related action by default.
You can handle the GridMenuItemClick event to:
- Perform custom actions
- Prevent the default action from being invoked after your event handler is complete, by setting the event's Handled parameter to true.

Example
The following example handles the GridView.GridMenuItemClick event to show a warning when you select the "Hide This Column" command from the column header menu. Pressing 'No' in the message box cancels the invoked action.
C# |
private void gridView1_GridMenuItemClick(object sender, DevExpress.XtraGrid.Views.Grid.GridMenuItemClickEventArgs e) {
if(e.MenuType == DevExpress.XtraGrid.Views.Grid.GridMenuType.Column) {
GridStringId value = e.DXMenuItem.Tag is GridStringId ? (GridStringId)e.DXMenuItem.Tag : 0 ;
if (value == GridStringId.MenuColumnRemoveColumn) {
if(MessageBox.Show("Do you want to hide this column?", "Warning", MessageBoxButtons.YesNo)== DialogResult.No) {
e.Handled = true;
}
}
}
}
|
VB |
Private Sub GridView1_GridMenuItemClick(sender As Object, e As GridMenuItemClickEventArgs) Handles GridView1.GridMenuItemClick
If e.MenuType = GridMenuType.Column Then
Dim value As GridStringId = If(TypeOf e.DXMenuItem.Tag Is GridStringId, CType(e.DXMenuItem.Tag, GridStringId), 0)
If value = GridStringId.MenuColumnRemoveColumn Then
If MessageBox.Show("Do you want to hide this column?", "Warning", MessageBoxButtons.YesNo) = DialogResult.No Then
e.Handled = True
End If
End If
End If
End Sub
|

Show a Custom Popup Menu for Any Grid Element
You can create and show a custom context menu within a View's BaseView.MouseDown event handler. When handling this event, identify the clicked element with the BaseView.CalcHitInfo method. This method returns information about a grid element at the specified screen point.
Use the GridViewMenu class to create a custom menu instance for Grid Views and Banded Grid Views. You can add the following menu item objects to the GridViewMenu.Items collection:

Example
This example creates a custom context menu that is displayed on right-clicking the Header Panel Button. This menu has two items: Columns and Runtime Column Customization. The first item is a sub menu that allows you to show/hide grid columns. The second item invokes the Customization Form.

C# |
private void gridView1_MouseDown(object sender, MouseEventArgs e) {
GridView view = sender as GridView;
if (e.Button == MouseButtons.Right)
DoShowMenu(view.CalcHitInfo(new Point(e.X, e.Y)));
}
void DoShowMenu(DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo hi) {
DevExpress.XtraGrid.Menu.GridViewMenu menu = null;
if (hi.HitTest == DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitTest.ColumnButton) {
menu = new GridViewColumnButtonMenu(hi.View);
menu.Init(hi);
menu.Show(hi.HitPoint);
}
}
public class GridViewColumnButtonMenu : GridViewMenu {
public GridViewColumnButtonMenu(DevExpress.XtraGrid.Views.Grid.GridView view) : base(view) { }
protected override void CreateItems() {
Items.Clear();
DXSubMenuItem submenuColumns = new DXSubMenuItem("Columns");
Items.Add(submenuColumns);
Items.Add(CreateMenuItem("Runtime Column Customization", GridMenuImages.Column.Images[3], "Customization", true));
foreach (GridColumn column in View.Columns) {
if (column.OptionsColumn.ShowInCustomizationForm && column.GroupIndex<0) {
submenuColumns.Items.Add(CreateMenuCheckItem(column.GetCaption(), column.Visible, null, column, true));
}
}
}
protected override void OnMenuItemCheckedChanged(object sender, EventArgs e) {
DXMenuCheckItem item = sender as DXMenuCheckItem;
if (item.Tag is GridColumn) {
GridColumn column = item.Tag as GridColumn;
column.Visible = item.Checked;
}
}
protected override void OnMenuItemClick(object sender, EventArgs e) {
DXMenuItem item = sender as DXMenuItem;
if (item.Tag == null) return;
if (item.Tag.ToString() == "Customization") View.ShowCustomization();
}
}
|
VB |
Private Sub GridView1_MouseDown(sender As Object, e As MouseEventArgs) Handles GridView1.MouseDown
Dim view As GridView = TryCast(sender, GridView)
If e.Button = MouseButtons.Right Then DoShowMenu(view.CalcHitInfo(New Point(e.X, e.Y)))
End Sub
Private Sub DoShowMenu(ByVal hi As GridHitInfo)
Dim menu As GridViewMenu = Nothing
If hi.HitTest = GridHitTest.ColumnButton Then
menu = New GridViewColumnButtonMenu(hi.View)
menu.Init(hi)
menu.Show(hi.HitPoint)
End If
End Sub
Public Class GridViewColumnButtonMenu
Inherits GridViewMenu
Public Sub New(ByVal view As GridView)
MyBase.New(view)
End Sub
Protected Overrides Sub CreateItems()
Items.Clear()
Dim submenuColumns As DXSubMenuItem = New DXSubMenuItem("Columns")
Items.Add(submenuColumns)
Items.Add(CreateMenuItem("Runtime Column Customization", GridMenuImages.Column.Images(3), "Customization", True))
For Each column As GridColumn In View.Columns
If column.OptionsColumn.ShowInCustomizationForm AndAlso column.GroupIndex < 0 Then
submenuColumns.Items.Add(CreateMenuCheckItem(column.GetCaption(), column.Visible, Nothing, column, True))
End If
Next
End Sub
Protected Overrides Sub OnMenuItemCheckedChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim item As DXMenuCheckItem = TryCast(sender, DXMenuCheckItem)
If TypeOf item.Tag Is GridColumn Then
Dim column As GridColumn = TryCast(item.Tag, GridColumn)
column.Visible = item.Checked
End If
End Sub
Protected Overrides Sub OnMenuItemClick(ByVal sender As Object, ByVal e As EventArgs)
Dim item As DXMenuItem = TryCast(sender, DXMenuItem)
If item.Tag Is Nothing Then Return
If item.Tag.ToString() = "Customization" Then View.ShowCustomization()
End Sub
End Class
|

Menu Appearance
By default, the Data Grid paints its menus according to the system settings, without taking into account the current skin.
To apply a skin to the Data Grid's menus, place a BarManager or RibbonControl component onto the form. This component is automatically bound to the Data Grid's EditorContainer.MenuManager property. The RibbonControl/BarManager now manages the display of the grid's menus, and applies the selected paint scheme (skin) to them.
The following image shows a column header menu painted using different themes.

You can use the Project Settings Page or the DefaultLookAndFeel component to customize the default paint scheme for all controls, including the data grid's popup menus.
Is this topic helpful?
Additional Feedback
Close
|