Back to Devexpress

Context Menus

wpf-6587-controls-and-libraries-data-grid-miscellaneous-context-menus.md

latest29.4 KB
Original Source

Context Menus

  • Jun 21, 2023
  • 8 minutes to read

The GridControl can display pop-up menus that allow users to manage data (apply grouping and sorting, display summaries, and so on) and customize the View (show or hide its UI elements). These context menus can be customized.

Context Menus Overview

|

Menu Type

|

Availability

|

Appearance

|

Item Names

| | --- | --- | --- | --- | |

Group Panel

|

IsGroupPanelMenuEnabled

|

|

DefaultColumnMenuItemNames.FullExpand

DefaultColumnMenuItemNames.FullCollapse

DefaultColumnMenuItemNames.ClearGrouping

| |

Column Header

|

IsColumnMenuEnabled

|

|

DefaultColumnMenuItemNamesBase.SortAscending

DefaultColumnMenuItemNamesBase.SortDescending

DefaultColumnMenuItemNamesBase.ClearSorting

DefaultColumnMenuItemNames.GroupColumn

DefaultColumnMenuItemNames.GroupBox

DefaultColumnMenuItemNamesBase.ColumnChooser

DefaultColumnMenuItemNames.BestFit

DefaultColumnMenuItemNames.BestFitColumns

DefaultColumnMenuItemNamesBase.FilterEditor

DefaultColumnMenuItemNamesBase.SearchPanel

DefaultColumnMenuItemNamesBase.FixedStyle

DefaultColumnMenuItemNamesBase.FixedNone

DefaultColumnMenuItemNamesBase.FixedLeft

DefaultColumnMenuItemNamesBase.FixedRight

| |

Group Column Header

|

IsColumnMenuEnabled

|

|

DefaultColumnMenuItemNames.FullExpand

DefaultColumnMenuItemNames.FullCollapse

DefaultColumnMenuItemNamesBase.SortAscending

DefaultColumnMenuItemNamesBase.SortDescending

DefaultColumnMenuItemNamesBase.ClearSorting

DefaultColumnMenuItemNames.UnGroupColumn

DefaultColumnMenuItemNames.GroupBox

DefaultColumnMenuItemNamesBase.ColumnChooser

DefaultColumnMenuItemNames.BestFitColumns

DefaultColumnMenuItemNames.GroupSummaryEditor

DefaultColumnMenuItemNamesBase.FilterEditor

DefaultColumnMenuItemNamesBase.SearchPanel

| |

Band Header

|

IsColumnMenuEnabled

|

|

DefaultColumnMenuItemNames.GroupBox

DefaultColumnMenuItemNamesBase.ColumnChooser

DefaultColumnMenuItemNames.BestFit

DefaultColumnMenuItemNames.BestFitColumns

DefaultColumnMenuItemNamesBase.FilterEditor

DefaultColumnMenuItemNamesBase.SearchPanel

DefaultColumnMenuItemNamesBase.FixedStyle

DefaultColumnMenuItemNamesBase.FixedNone

DefaultColumnMenuItemNamesBase.FixedLeft

DefaultColumnMenuItemNamesBase.FixedRight

| |

Row Cell

|

IsRowCellMenuEnabled

|

|

| |

Group Row

|

IsGroupRowMenuEnabled

|

|

| |

Summary Panel

Group Footer

|

IsTotalSummaryMenuEnabled

IsGroupFooterMenuEnabled

|

|

DefaultSummaryMenuItemNames.Sum

DefaultSummaryMenuItemNames.Min

DefaultSummaryMenuItemNames.Max

DefaultSummaryMenuItemNames.Count

DefaultSummaryMenuItemNames.Average

DefaultSummaryMenuItemNames.Customize

| |

Fixed Summary Panel

|

IsTotalSummaryMenuEnabled

|

|

DefaultSummaryMenuItemNames.Count

DefaultSummaryMenuItemNames.Customize

|

To obtain the context menu displayed within a View, use the GridViewBase.GridMenu property.

Customize Context Menus

In XAML

Use the View’s properties:

|

Menu Type

|

Property

| | --- | --- | |

Group Panel

|

GridViewBase.GroupPanelMenuCustomizations

| |

Column Header

|

DataViewBase.ColumnMenuCustomizations

| |

Band Header

|

TableView.BandMenuCustomizations

| |

Row Cell

|

DataViewBase.RowCellMenuCustomizations

| |

Group Row

|

GridViewBase.GroupRowMenuCustomizations

| |

Summary

|

DataViewBase.TotalSummaryMenuCustomizations

| |

Group Footer

|

GridViewBase.GroupFooterMenuCustomizations

| |

Compact Panel

|

TableView

TableView.CompactModeFilterElementMenuCustomizations

TableView.CompactModeFilterMergeElementMenuCustomizations

TableView.CompactModeSortElementMenuCustomizations

| | |

TreeListView

TreeListView.CompactModeFilterElementMenuCustomizations

TreeListView.CompactModeFilterMergeElementMenuCustomizations

TreeListView.CompactModeSortElementMenuCustomizations

|

These properties return a BarManagerActionCollection object (bar items, links, and actions).

In Code

Handle the DataViewBase.ShowGridMenu event.

Examples

Bind to a Column, Row, and TableView in RowCellMenuCustomizations

To bind a cell’s context menu to a column, row, or TableView, use the default binding source or the attached GridPopupMenu.GridMenuInfo property.

xaml
<Window ...
        xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
        xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars">
<!-- ... -->
<dxg:TableView Tag="Test value">
    <dxg:TableView.RowCellMenuCustomizations>
        <dxb:BarButtonItem Content="{Binding Path=Column.FieldName}" />
        <dxb:BarButtonItem Content="{Binding Path=Row.Row.Name}" />
        <dxb:BarButtonItem Content="{Binding Path=View.Tag}" />
    </dxg:TableView.RowCellMenuCustomizations>
</dxg:TableView>
<!-- OR -->
<dxg:TableView Tag="Test value">
    <dxg:TableView.RowCellMenuCustomizations>
        <dxb:BarButtonItem Content="{Binding Path=(dxg:GridPopupMenu.GridMenuInfo).Column.FieldName, RelativeSource={RelativeSource Self}}" />
        <dxb:BarButtonItem Content="{Binding Path=(dxg:GridPopupMenu.GridMenuInfo).Row.Row.Name, RelativeSource={RelativeSource Self}}" />
        <dxb:BarButtonItem Content="{Binding Path=(dxg:GridPopupMenu.GridMenuInfo).View.Tag, RelativeSource={RelativeSource Self}}" />
    </dxg:TableView.RowCellMenuCustomizations>
</dxg:TableView>

Rename Standard Menu Items

The following example renames the “Customize…” item in the summary panel:

In XAML

Use the bar‘s UpdateAction and specify the item name.

xaml
<dxg:TableView.TotalSummaryMenuCustomizations>
    <dxb:UpdateAction ElementName="{x:Static dxg:DefaultSummaryMenuItemNames.Customize}" PropertyName="Content" Value="Edit..." />
</dxg:TableView.TotalSummaryMenuCustomizations>

In Code

Subscribe to the DataViewBase.ShowGridMenu event and change the item name.

xaml
<dxg:TableView ShowGridMenu="ShowGridMenu" />
csharp
using DevExpress.Xpf.Grid;
using DevExpress.Xpf.Bars;
//...
void ShowGridMenu(object sender, GridMenuEventArgs e) {
    if (e.MenuType != GridMenuType.TotalSummary)
        return;
    BarItem item = e.Items.FirstOrDefault(x => x.Name == DefaultSummaryMenuItemNames.Customize);
    if (item != null)
        item.Content = "Edit...";
}
vb
Imports DevExpress.Xpf.Grid
Imports DevExpress.Xpf.Bars
' ...
Sub ShowGridMenu(sender As Object, e As GridMenuEventArgs)
    If e.MenuType = GridMenuType.TotalSummary Then
        Dim item As BarItem = e.Items.FirstOrDefault(Function(x) x.Name = DefaultSummaryMenuItemNames.Customize)
        If item IsNot Nothing Then item.Content = "Edit..."
    End If
End Sub

Add Cell and Column Menu Items to a Column

In XAML

Use the RowCellMenuCustomizations/ColumnMenuCustomizations properties and binding paths from the Bind to a Column, Row, and TableView in RowCellMenuCustomizations example.

xaml
<Window.Resources>
    <dxmvvm:ObjectToObjectConverter x:Key="fieldNameToVisibleConverter" DefaultTarget="False">
        <dxmvvm:MapItem Source="Visits" Target="True" />
    </dxmvvm:ObjectToObjectConverter>
</Window.Resources>
...
<dxg:TableView>
    <dxg:TableView.RowCellMenuCustomizations>
        <dxb:BarButtonItem Content="Item 1" IsVisible="{Binding Column.FieldName, Converter={StaticResource fieldNameToVisibleConverter}}" />
    </dxg:TableView.RowCellMenuCustomizations>
    <dxg:TableView.ColumnMenuCustomizations>
        <dxb:BarButtonItem Content="Item 2" IsVisible="{Binding Column.FieldName, Converter={StaticResource fieldNameToVisibleConverter}}" />
    </dxg:TableView.ColumnMenuCustomizations>
</dxg:TableView>

In Code

Subscribe to the DataViewBase.ShowGridMenu event and specify e.MenuInfo.Column.FieldName in the event handler.

xaml
<dxg:TableView ShowGridMenu="TableView_ShowGridMenu" />
csharp
void TableView_ShowGridMenu(object sender, GridMenuEventArgs e) {
    if (e.MenuInfo.Column.FieldName != "Visits")
        return;
    switch (e.MenuType) {
        case GridMenuType.RowCell:
            e.Customizations.Add(new BarButtonItem { Content = "Item 1" });
            break;
        case GridMenuType.Column:
            e.Customizations.Add(new BarButtonItem { Content = "Item 2" });
            break;
    }
}
vb
Sub TableView_ShowGridMenu(sender As Object, e As GridMenuEventArgs)
    If e.MenuInfo.Column.FieldName <> "Visits" Then Return
    Select Case e.MenuType
        Case GridMenuType.RowCell
            e.Customizations.Add(New BarButtonItem With {.Content = "Item 1"})
        Case GridMenuType.Column
            e.Customizations.Add(New BarButtonItem With {.Content = "Item 2"})
    End Select
End Sub

Show Different Cell Menu Items Depending on a Property Value

The following example demonstrates how to show the row cell’s context menu item if you sort data against the current column:

In XAML

Use RowCellMenuCustomizations and binding paths from the Bind to a Column, Row, and TableView in RowCellMenuCustomizations example.

xaml
<dxg:TableView>
    <dxg:TableView.RowCellMenuCustomizations>
        <dxb:BarButtonItem Content="Item 1" IsVisible="{Binding Column.IsSorted}" />
        <dxb:BarButtonItem Content="Item 2" />
    </dxg:TableView.RowCellMenuCustomizations>
</dxg:TableView>

In Code

Subscribe to the DataViewBase.ShowGridMenu event and get column objects from e.MenuInfo.

xaml
<dxg:TableView ShowGridMenu="TableView_ShowGridMenu" />
csharp
void TableView_ShowGridMenu(object sender, GridMenuEventArgs e)
{
    if (e.MenuType != GridMenuType.RowCell)
        return;
    GridCellMenuInfo info = (GridCellMenuInfo)e.MenuInfo;
    ColumnBase item = (ColumnBase)info.Column;
    if (item.IsSorted)
        e.Customizations.Add(new BarButtonItem { Content = "Item 1" });
    e.Customizations.Add(new BarButtonItem { Content = "Item 2" });
}
vb
Private Sub TableView_ShowGridMenu(ByVal sender As Object, ByVal e As GridMenuEventArgs)
    If e.MenuType <> GridMenuType.RowCell Then Return
    Dim info As GridCellMenuInfo = CType(e.MenuInfo, GridCellMenuInfo)
    Dim item As ColumnBase = CType(info.Column, ColumnBase)
    If item.IsSorted Then e.Customizations.Add(New BarButtonItem With {
        .Content = "Item 1" })
    e.Customizations.Add(New BarButtonItem With {
        .Content = "Item 2" })
End Sub

Show Different Cell Menu Items Depending on a Node Level

The following example demonstrates how to show a row cell’s context menu for a node level:

In XAML

Use the RowCellMenuCustomizations property and bind the BarItem.IsVisible property to the current node’s level.

xaml
<Window.Resources>
    <dxmvvm:ObjectToObjectConverter x:Key="levelToVisibleConverter" DefaultTarget="False">
        <dxmvvm:MapItem Source="1" Target="True" />
    </dxmvvm:ObjectToObjectConverter>
</Window.Resources>
...
<dxg:TreeListView>
    <dxg:TreeListView.RowCellMenuCustomizations>
        <dxb:BarButtonItem Content="Item 1" IsVisible="{Binding Row.Level, Converter={StaticResource levelToVisibleConverter}}" />
    </dxg:TreeListView.RowCellMenuCustomizations>
</dxg:TreeListView>

In Code

Subscribe to the DataViewBase.ShowGridMenu event and get the current node from the e.MenuInfo object.

xaml
<dxg:TreeListView ShowGridMenu="TreeListView_ShowGridMenu" />
csharp
void TreeListView_ShowGridMenu(object sender, GridMenuEventArgs e) {
    if (e.MenuType != GridMenuType.RowCell)
        return;
    GridCellMenuInfo info = (GridCellMenuInfo)e.MenuInfo;
    TreeListRowData rowData = (TreeListRowData)info.Row;
    if (rowData.Level == 1)
        e.Customizations.Add(new BarButtonItem { Content = "Item 1" });
}
vb
Sub TreeListView_ShowGridMenu(sender As Object, e As GridMenuEventArgs)
    If e.MenuType <> GridMenuType.RowCell Then Return
    Dim info = DirectCast(e.MenuInfo, GridCellMenuInfo)
    Dim rowData = DirectCast(info.Row, TreeListRowData)
    If rowData.Level = 1 Then
        e.Customizations.Add(New BarButtonItem With {.Content = "Item 1"})
    End If
End Sub

Remove Menu Items

The following example removes an item from the Total Summary panel‘s context menu :

View Example: Customize the GridControl's Context Menu

In XAML

Add the RemoveBarItemAndLinkAction object to the DataViewBase.TotalSummaryMenuCustomizations collection. Specify the BarItemActionBase.ItemName property with the menu item name from the DefaultSummaryMenuItemNames class.

xaml
<dxg:TableView.TotalSummaryMenuCustomizations>
    <dxb:RemoveBarItemAndLinkAction ItemName="{x:Static dxg:DefaultSummaryMenuItemNames.Customize}"/>
</dxg:TableView.TotalSummaryMenuCustomizations>

In Code

Handle the DataViewBase.ShowGridMenu event.

xaml
<dxg:TableView ShowGridMenu="ShowGridMenu"/>
csharp
void ShowGridMenu(object sender, GridMenuEventArgs e) {
    if (e.MenuType == GridMenuType.TotalSummary) {
        e.Customizations.Add(new RemoveAction { ElementName = DefaultSummaryMenuItemNames.Customize });
    }
}
vb
Sub ShowGridMenu(sender As Object, e As GridMenuEventArgs)
    If e.MenuType = GridMenuType.TotalSummary Then
        e.Customizations.Add(New RemoveAction() With {.ElementName = DefaultSummaryMenuItemNames.Customize})
    End If
End Sub

Add Menu Items to a Specific Position

The following example demonstrates how to add a custom menu item to a grid column’s context menu :

View Example: Customize the GridControl's Context Menu

In XAML

Add a bar item (for example, BarCheckItem) to the DataViewBase.ColumnMenuCustomizations collection and specify item properties. Attach the BarItemLinkActionBase.ItemLinkIndex property to this item to insert it into a specific position.

xaml
<dxg:TableView.ColumnMenuCustomizations>
    <dxb:BarCheckItem Content="Checked" IsChecked="True" dxb:BarItemLinkActionBase.ItemLinkIndex="0"/>
    <dxb:BarItemLinkSeparator dxb:BarItemLinkActionBase.ItemLinkIndex="1"/>
</dxg:TableView.ColumnMenuCustomizations>

In Code

Handle the ShowGridMenu event.

xaml
<dxg:TableView ShowGridMenu="ShowGridMenu"/>
csharp
void ShowGridMenu(object sender, GridMenuEventArgs e) {
    if (e.MenuType == GridMenuType.Column) {
        BarCheckItem item1 = new BarCheckItem { Content = "Checked", IsChecked = true };
        BarItemLinkActionBase.SetItemLinkIndex(item1, 0);
        e.Customizations.Add(item1);
        BarItemLinkSeparator item2 = new BarItemLinkSeparator();
        BarItemLinkActionBase.SetItemLinkIndex(item2, 1);
        e.Customizations.Add(item2);
    }
}
vb
Sub ShowGridMenu(sender As Object, e As GridMenuEventArgs)
    If e.MenuType = GridMenuType.Column Then
        Dim item1 As BarCheckItem = New BarCheckItem() With {.Content = "Checked", .IsChecked = True}
        BarItemLinkActionBase.SetItemLinkIndex(item1, 0)
        e.Customizations.Add(item1)
        Dim item2 As BarItemLinkSeparator = New BarItemLinkSeparator()
        BarItemLinkActionBase.SetItemLinkIndex(item2, 1)
        e.Customizations.Add(item2)
    End If
End Sub

Add Custom Row Cell’s Context Menu

This example shows how to define a cell’s context menu. The context menu allows users to delete a row or copy its data to the clipboard.

View Example: Display a Context Menu for Data Cells

xaml
<dxg:GridControl.View>
    <dxg:TableView x:Name="view" AutoWidth="True">
        <dxg:TableView.RowCellMenuCustomizations>
            <dxb:BarButtonItem Name="deleteRowItem" Content="Delete"
                               IsEnabled="{Binding Row.Row.CanBeDeleted}"
                               ItemClick="OnDeleteRow"/>
            <dxb:BarButtonItem Name="copyCellDataItem" Content="Copy" 
                               ItemClick="OnCopyRow" />
        </dxg:TableView.RowCellMenuCustomizations>
    </dxg:TableView>
</dxg:GridControl.View>
cs
void OnCopyRow(object sender, ItemClickEventArgs e) {
    if (view.GridMenu.MenuInfo is GridCellMenuInfo menuInfo && menuInfo.Row != null)
        grid.CopyCurrentItemToClipboard();
}
void OnDeleteRow(object sender, ItemClickEventArgs e) {
    if (view.GridMenu.MenuInfo is GridCellMenuInfo menuInfo && menuInfo.Row != null)
        view.DeleteRow(menuInfo.Row.RowHandle.Value);
}
vb
Private Sub copyCellDataItem_ItemClick(ByVal sender As Object, ByVal e As ItemClickEventArgs)
    Dim menuInfo As GridCellMenuInfo = TryCast(view.GridMenu.MenuInfo, GridCellMenuInfo)
    If menuInfo IsNot Nothing AndAlso menuInfo.Row IsNot Nothing Then
        grid.CopyCurrentItemToClipboard()
    End If
End Sub

Private Sub deleteRowItem_ItemClick(ByVal sender As Object, ByVal e As ItemClickEventArgs)
    Dim menuInfo As GridCellMenuInfo = TryCast(view.GridMenu.MenuInfo, GridCellMenuInfo)
    If menuInfo IsNot Nothing AndAlso menuInfo.Row IsNot Nothing Then
        view.DeleteRow(menuInfo.Row.RowHandle.Value)
    End If
End Sub

Add a Context Menu to an Empty Grid

The following example shows how to add a context menu for an empty GridControl:

  1. Create the BarManager.DXContextMenu object.
  2. Create a new instance of the PopupMenu class and assign it to the BarManager.DXContextMenu object.
  3. Add bar items (for example, BarButtonItem objects) to the PopupMenu.Items collection.
xaml
<Window xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
        xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars">
    <dxg:GridControl ...>
        <dxb:BarManager.DXContextMenu>
            <dxb:PopupMenu>
                <dxb:PopupMenu.Items>
                    <dxb:BarButtonItem Content="Item 1"/>
                    <dxb:BarButtonItem Content="Item 2"/>
                </dxb:PopupMenu.Items>
            </dxb:PopupMenu>
        </dxb:BarManager.DXContextMenu>
    </dxg:GridControl>
</Window>

Disable all the GridControl’s Context Menus

If you do not want to display any of the GridControl‘s context menus, follow the steps below:

  1. Handle the DataViewBase.ShowGridMenu event.
  2. In the event handler, set the e.Handled property to true.
xaml
<dxg:GridControl.View>
    <dxg:TableView ShowGridMenu="view_ShowGridMenu"/>
</dxg:GridControl.View>
csharp
void view_ShowGridMenu(object sender, GridMenuEventArgs e) {
    e.Handled = true;
}
vb
Private Sub view_ShowGridMenu(ByVal sender As Object, ByVal e As GridMenuEventArgs)
    e.Handled = True
End Sub