From 0ddec0c3951dd897c57d306b5eb7b04c42640a61 Mon Sep 17 00:00:00 2001 From: iancaringal-devexpress Date: Mon, 6 Apr 2026 17:25:17 +0800 Subject: [PATCH 1/9] updated grid to use built in context menu --- .../Data/WeatherForecastService.cs | 2 +- .../GridWithContextMenu.csproj | 2 +- CS/GridWithContextMenu/Pages/Index.razor | 97 +++++++++++++++++-- 3 files changed, 89 insertions(+), 12 deletions(-) diff --git a/CS/GridWithContextMenu/Data/WeatherForecastService.cs b/CS/GridWithContextMenu/Data/WeatherForecastService.cs index a92bdd0..cc4ecb4 100644 --- a/CS/GridWithContextMenu/Data/WeatherForecastService.cs +++ b/CS/GridWithContextMenu/Data/WeatherForecastService.cs @@ -8,7 +8,7 @@ public enum Summaries { public Task> GetForecastAsync() { if (Forecasts == null) { var rnd = new Random(); - Forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast { + Forecasts = Enumerable.Range(1, 25).Select(index => new WeatherForecast { ID = index, Date = DateTime.Today.AddDays(index), TemperatureC = rnd.Next(-20, 55), diff --git a/CS/GridWithContextMenu/GridWithContextMenu.csproj b/CS/GridWithContextMenu/GridWithContextMenu.csproj index 08c7248..8fa22e6 100644 --- a/CS/GridWithContextMenu/GridWithContextMenu.csproj +++ b/CS/GridWithContextMenu/GridWithContextMenu.csproj @@ -8,6 +8,6 @@ - + diff --git a/CS/GridWithContextMenu/Pages/Index.razor b/CS/GridWithContextMenu/Pages/Index.razor index fdcf795..4ddc944 100644 --- a/CS/GridWithContextMenu/Pages/Index.razor +++ b/CS/GridWithContextMenu/Pages/Index.razor @@ -8,14 +8,37 @@ EditMode="GridEditMode.EditRow" CssClass="mw-1100" CustomizeElement="Grid_CustomizeElement" - @oncontextmenu:preventDefault EditModelSaving="Grid_EditModelSaving" - DataItemDeleting="Grid_DataItemDeleting"> + DataItemDeleting="Grid_DataItemDeleting" + ContextMenus="GridContextMenus.All" + CustomizeContextMenu="Grid_CustomizeContextMenu"> + + + + + + + + + + + + + + + + + - + - + @@ -28,18 +51,47 @@ IGrid Grid { get; set; } GridContextMenuContainer ContextMenuContainer { get; set; } object GridData { get; set; } + string GridSearchText = ""; + const string ExportFileName = "ExportResult"; protected override async Task OnInitializedAsync() { GridData = await ForecastService.GetForecastAsync(); } + void Grid_CustomizeContextMenu(GridCustomizeContextMenuEventArgs args) + { + if (args.Context is GridDataRowCommandContext rowContext) + { + args.Items.AddCustomItem("New Row", async () => + { + rowContext.Grid.BeginUpdate(); + await rowContext.Grid.StartEditNewRowAsync(); + rowContext.Grid.EndUpdate(); + }); + args.Items.AddCustomItem("Edit Row", async () => + { + rowContext.Grid.BeginUpdate(); + await rowContext.Grid.StartEditRowAsync(rowContext.RowVisibleIndex); + rowContext.Grid.EndUpdate(); + }); + args.Items.AddCustomItem("Delete Row", async () => + { + rowContext.Grid.BeginUpdate(); + rowContext.Grid.ShowRowDeleteConfirmation(rowContext.RowVisibleIndex); + rowContext.Grid.EndUpdate(); + }); + args.Items.Add(GridContextMenuDefaultItemNames.ExpandAll); + args.Items.Add(GridContextMenuDefaultItemNames.CollapseAll); + } + } + void Grid_CustomizeElement(GridCustomizeElementEventArgs e) { - if(GridContextMenuHelper.IsContextMenuElement(e.ElementType)) { - e.Attributes["oncontextmenu"] = EventCallback.Factory.Create( - this, - async mArgs => await ContextMenuContainer.Grid_ContextMenu(e, mArgs) - ); - } + // if(GridContextMenuHelper.IsContextMenuElement(e.ElementType)) { + // e.Attributes["oncontextmenu"] = EventCallback.Factory.Create( + // this, + // async mArgs => await ContextMenuContainer.Grid_ContextMenu(e, mArgs) + // ); + // } } async Task Grid_EditModelSaving(GridEditModelSavingEventArgs e) { @@ -51,4 +103,29 @@ await ForecastService.Remove(item); } } + + async Task NewItem_Click() + { + await Grid.StartEditNewRowAsync(); + } + void ColumnChooserItem_Click(ToolbarItemClickEventArgs e) + { + Grid.ShowColumnChooser(); + } + async Task ExportXlsxItem_Click() + { + await Grid.ExportToXlsxAsync(ExportFileName); + } + async Task ExportXlsItem_Click() + { + await Grid.ExportToXlsAsync(ExportFileName); + } + async Task ExportCsvItem_Click() + { + await Grid.ExportToCsvAsync(ExportFileName); + } + async Task ExportPdfItem_Click() + { + await Grid.ExportToPdfAsync(ExportFileName); + } } \ No newline at end of file From c14636102aecf9831009a46acb8044587dec22ab Mon Sep 17 00:00:00 2001 From: iancaringal-devexpress Date: Tue, 7 Apr 2026 15:16:07 +0800 Subject: [PATCH 2/9] add context menu items to row context menu --- .../Data/GridContextMenuHelper.cs | 4 +-- CS/GridWithContextMenu/Pages/Index.razor | 32 +++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs index dd18154..521ae1b 100644 --- a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs +++ b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs @@ -65,7 +65,7 @@ static List CreateRowContextMenuItems() { } public static bool IsContextMenuElement(GridElementType elementType) { - return IsColumnContextMenuElement(elementType) || IsRowContextMenuElement(elementType); + return IsRowContextMenuElement(elementType); } public static bool IsColumnContextMenuElement(GridElementType elementType) { switch(elementType) { @@ -79,8 +79,6 @@ public static bool IsColumnContextMenuElement(GridElementType elementType) { } public static bool IsRowContextMenuElement(GridElementType elementType) { switch(elementType) { - case GridElementType.DataRow: - case GridElementType.GroupRow: case GridElementType.EditRow: return true; } diff --git a/CS/GridWithContextMenu/Pages/Index.razor b/CS/GridWithContextMenu/Pages/Index.razor index 4ddc944..d3e86c2 100644 --- a/CS/GridWithContextMenu/Pages/Index.razor +++ b/CS/GridWithContextMenu/Pages/Index.razor @@ -11,7 +11,8 @@ EditModelSaving="Grid_EditModelSaving" DataItemDeleting="Grid_DataItemDeleting" ContextMenus="GridContextMenus.All" - CustomizeContextMenu="Grid_CustomizeContextMenu"> + CustomizeContextMenu="Grid_CustomizeContextMenu" + > @@ -61,6 +62,21 @@ { if (args.Context is GridDataRowCommandContext rowContext) { + if (rowContext.Grid.IsEditing()) + { + args.Items.AddCustomItem("Save Changes", async () => + { + rowContext.Grid.BeginUpdate(); + await rowContext.Grid.SaveChangesAsync(); + rowContext.Grid.EndUpdate(); + }); + args.Items.AddCustomItem("Cancel Editing", async () => + { + rowContext.Grid.BeginUpdate(); + await rowContext.Grid.CancelEditAsync(); + rowContext.Grid.EndUpdate(); + }); + } args.Items.AddCustomItem("New Row", async () => { rowContext.Grid.BeginUpdate(); @@ -79,19 +95,17 @@ rowContext.Grid.ShowRowDeleteConfirmation(rowContext.RowVisibleIndex); rowContext.Grid.EndUpdate(); }); - args.Items.Add(GridContextMenuDefaultItemNames.ExpandAll); - args.Items.Add(GridContextMenuDefaultItemNames.CollapseAll); } } void Grid_CustomizeElement(GridCustomizeElementEventArgs e) { - // if(GridContextMenuHelper.IsContextMenuElement(e.ElementType)) { - // e.Attributes["oncontextmenu"] = EventCallback.Factory.Create( - // this, - // async mArgs => await ContextMenuContainer.Grid_ContextMenu(e, mArgs) - // ); - // } + if(GridContextMenuHelper.IsContextMenuElement(e.ElementType)) { + e.Attributes["oncontextmenu"] = EventCallback.Factory.Create( + this, + async mArgs => await ContextMenuContainer.Grid_ContextMenu(e, mArgs) + ); + } } async Task Grid_EditModelSaving(GridEditModelSavingEventArgs e) { From 9bc2fcbb7e7d59bdbf0da39507564341083ed5f6 Mon Sep 17 00:00:00 2001 From: iancaringal-devexpress Date: Fri, 17 Apr 2026 17:14:35 +0800 Subject: [PATCH 3/9] Added custom items to built-in column context menu --- .../Data/GridContextMenuHelper.cs | 60 ++----------- .../Pages/GridContextMenuContainer.razor | 2 +- CS/GridWithContextMenu/Pages/Index.razor | 90 ++++++++++++------- 3 files changed, 67 insertions(+), 85 deletions(-) diff --git a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs index 521ae1b..4d8c591 100644 --- a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs +++ b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs @@ -33,18 +33,8 @@ static List CreateColumnContextMenuItems() { return new List { new ContextMenuItem { ItemType = GridContextMenuItemType.FullExpand, Text = "Expand All", IconCssClass="grid-context-menu-item-full-expand" }, new ContextMenuItem { ItemType = GridContextMenuItemType.FullCollapse, Text = "Collapse All", IconCssClass="grid-context-menu-item-full-collapse" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.SortAscending, Text = "Sort Ascending", BeginGroup = true, IconCssClass="grid-context-menu-item-sort-ascending" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.SortDescending, Text = "Sort Descending", IconCssClass="grid-context-menu-item-sort-descending" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.ClearSorting, Text = "Clear Sorting" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.GroupByColumn, Text = "Group By This Column", BeginGroup = true, IconCssClass="grid-context-menu-item-group-by-column" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.UngroupColumn, Text = "Ungroup", IconCssClass="grid-context-menu-item-ungroup-column" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.ClearGrouping, Text = "Clear Grouping", IconCssClass="grid-context-menu-item-clear-grouping" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowGroupPanel, Text = "Group Panel", IconCssClass="grid-context-menu-item-show-group-panel" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.HideColumn, Text = "Hide Column", BeginGroup = true, IconCssClass="grid-context-menu-item-hide-column" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowColumnChooser, Text = "Column Chooser", IconCssClass="grid-context-menu-item-column-chooser" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.FixColumnToLeft, Text = "Fix Column to the Left", BeginGroup = true, IconCssClass="grid-context-menu-item-fix-column-left" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.FixColumnToRight, Text = "Fix Column to the Right", IconCssClass="grid-context-menu-item-fix-column-right" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.Unfix, Text = "Unfix Column", IconCssClass="grid-context-menu-item-unfix-column" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ClearFilter, Text = "Clear Filter", BeginGroup = true, IconCssClass="grid-context-menu-item-clear-filter" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowFilterRow, Text = "Filter Row", IconCssClass="grid-context-menu-item-filter-row" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowFooter, Text = "Footer", IconCssClass="grid-context-menu-item-footer" } @@ -65,15 +55,13 @@ static List CreateRowContextMenuItems() { } public static bool IsContextMenuElement(GridElementType elementType) { - return IsRowContextMenuElement(elementType); + return IsCustomContextMenuElement(elementType) || IsRowContextMenuElement(elementType); } - public static bool IsColumnContextMenuElement(GridElementType elementType) { + public static bool IsCustomContextMenuElement(GridElementType elementType) { switch(elementType) { - case GridElementType.HeaderCell: - case GridElementType.HeaderCommandCell: - case GridElementType.HeaderSelectionCell: - case GridElementType.GroupPanelHeader: - return true; + //case GridElementType.ToolbarContainer: + //case GridElementType.PagerContainer: + // return true; } return false; } @@ -95,30 +83,6 @@ public static void ProcessColumnMenuItemClick(ContextMenuItem item, IGridColumn case GridContextMenuItemType.FullCollapse: grid.CollapseAllGroupRows(); break; - case GridContextMenuItemType.SortAscending: - if(dataColumn.SortOrder != GridColumnSortOrder.Ascending) { - var newSortIndex = dataColumn.SortIndex > -1 ? dataColumn.SortIndex : grid.GetSortedColumns().Count; - grid.SortBy(dataColumn.FieldName, GridColumnSortOrder.Ascending, newSortIndex); - } - break; - case GridContextMenuItemType.SortDescending: - if(dataColumn.SortOrder != GridColumnSortOrder.Descending) { - var newSortIndex = dataColumn.SortIndex > -1 ? dataColumn.SortIndex : grid.GetSortedColumns().Count; - grid.SortBy(dataColumn.FieldName, GridColumnSortOrder.Descending, newSortIndex); - } - break; - case GridContextMenuItemType.ClearSorting: - grid.SortBy(dataColumn.FieldName, GridColumnSortOrder.Descending, -1); - break; - case GridContextMenuItemType.GroupByColumn: - grid.GroupBy(dataColumn.FieldName, grid.GetGroupCount()); - break; - case GridContextMenuItemType.UngroupColumn: - grid.GroupBy(dataColumn.FieldName, -1); - break; - case GridContextMenuItemType.ClearGrouping: - grid.ClearSort(); - break; case GridContextMenuItemType.ShowGroupPanel: grid.ShowGroupPanel = !grid.ShowGroupPanel; break; @@ -129,22 +93,10 @@ public static void ProcessColumnMenuItemClick(ContextMenuItem item, IGridColumn var isFooterVisible = grid.FooterDisplayMode == GridFooterDisplayMode.Always || grid.FooterDisplayMode == GridFooterDisplayMode.Auto && grid.GetTotalSummaryItems().Count > 0; grid.FooterDisplayMode = isFooterVisible ? GridFooterDisplayMode.Never : GridFooterDisplayMode.Always; - break; - case GridContextMenuItemType.HideColumn: - column.Visible = false; - break; + break; case GridContextMenuItemType.ShowColumnChooser: grid.ShowColumnChooser(); break; - case GridContextMenuItemType.FixColumnToLeft: - column.FixedPosition = GridColumnFixedPosition.Left; - break; - case GridContextMenuItemType.FixColumnToRight: - column.FixedPosition = GridColumnFixedPosition.Right; - break; - case GridContextMenuItemType.Unfix: - column.FixedPosition = GridColumnFixedPosition.None; - break; case GridContextMenuItemType.ClearFilter: grid.ClearFilter(); break; diff --git a/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor b/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor index 1756045..e0fed7a 100644 --- a/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor +++ b/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor @@ -46,7 +46,7 @@ => await GridContextMenuHelper.ProcessRowMenuItemClickAsync((ContextMenuItem)e.ItemInfo.DataItem, ContextMenuRowIndex, Grid); public async Task Grid_ContextMenu(GridCustomizeElementEventArgs e, MouseEventArgs mouseArgs) { - if(GridContextMenuHelper.IsColumnContextMenuElement(e.ElementType)) { + if(GridContextMenuHelper.IsCustomContextMenuElement(e.ElementType)) { ContextMenuColumn = e.Column; ColumnContextMenuData = GridContextMenuHelper.GetColumnItems(e); await ColumnContextMenu.ShowAsync(mouseArgs); diff --git a/CS/GridWithContextMenu/Pages/Index.razor b/CS/GridWithContextMenu/Pages/Index.razor index d3e86c2..b42a1e6 100644 --- a/CS/GridWithContextMenu/Pages/Index.razor +++ b/CS/GridWithContextMenu/Pages/Index.razor @@ -12,7 +12,7 @@ DataItemDeleting="Grid_DataItemDeleting" ContextMenus="GridContextMenus.All" CustomizeContextMenu="Grid_CustomizeContextMenu" - > + @oncontextmenu:preventDefault> @@ -58,44 +58,80 @@ protected override async Task OnInitializedAsync() { GridData = await ForecastService.GetForecastAsync(); } - void Grid_CustomizeContextMenu(GridCustomizeContextMenuEventArgs args) - { - if (args.Context is GridDataRowCommandContext rowContext) - { - if (rowContext.Grid.IsEditing()) - { - args.Items.AddCustomItem("Save Changes", async () => - { + void Grid_CustomizeContextMenu(GridCustomizeContextMenuEventArgs args) { + if (args.Context is GridDataRowCommandContext rowContext) { + if (rowContext.Grid.IsEditing()) { + args.Items.AddCustomItem("Save", async () => { rowContext.Grid.BeginUpdate(); await rowContext.Grid.SaveChangesAsync(); rowContext.Grid.EndUpdate(); }); - args.Items.AddCustomItem("Cancel Editing", async () => - { + args.Items.AddCustomItem("Cancel", async () => { rowContext.Grid.BeginUpdate(); await rowContext.Grid.CancelEditAsync(); rowContext.Grid.EndUpdate(); }); } - args.Items.AddCustomItem("New Row", async () => - { + args.Items.AddCustomItem("New", async () => { rowContext.Grid.BeginUpdate(); await rowContext.Grid.StartEditNewRowAsync(); rowContext.Grid.EndUpdate(); - }); - args.Items.AddCustomItem("Edit Row", async () => - { + }).BeginGroup = true; + args.Items.AddCustomItem("Edit", async () => { rowContext.Grid.BeginUpdate(); await rowContext.Grid.StartEditRowAsync(rowContext.RowVisibleIndex); rowContext.Grid.EndUpdate(); }); - args.Items.AddCustomItem("Delete Row", async () => - { + args.Items.AddCustomItem("Delete", async () => { rowContext.Grid.BeginUpdate(); rowContext.Grid.ShowRowDeleteConfirmation(rowContext.RowVisibleIndex); rowContext.Grid.EndUpdate(); }); } + + if (args.Context is GridHeaderCommandContext headerContext) { + var isFilterRowVisible = headerContext.Grid.ShowFilterRow != false; + string filterRowItemText = isFilterRowVisible ? "Hide Filter Row" : "Show Filter Row"; + var newFilterRowState = isFilterRowVisible ? false : true; + args.Items.AddCustomItem(filterRowItemText, () => { + headerContext.Grid.BeginUpdate(); + headerContext.Grid.ShowFilterRow = newFilterRowState; + headerContext.Grid.EndUpdate(); + }); + + var isFiltered = headerContext.Grid.GetFilterCriteria() != null; + args.Items.AddCustomItem("Clear Filter", () => { + headerContext.Grid.BeginUpdate(); + headerContext.Grid.ClearFilter(); + headerContext.Grid.EndUpdate(); + }).Enabled = isFiltered ? true : false; + + args.Items.AddCustomItem("Fix Column to the Left", () => { + headerContext.Grid.BeginUpdate(); + headerContext.Column.FixedPosition = GridColumnFixedPosition.Left; + headerContext.Grid.EndUpdate(); + }).BeginGroup = true; + args.Items.AddCustomItem("Fix Column to the Right", () => { + headerContext.Grid.BeginUpdate(); + headerContext.Column.FixedPosition = GridColumnFixedPosition.Right; + headerContext.Grid.EndUpdate(); + }); + args.Items.AddCustomItem("Unfix Column", () => { + headerContext.Grid.BeginUpdate(); + headerContext.Column.FixedPosition = GridColumnFixedPosition.None; + headerContext.Grid.EndUpdate(); + }); + + var isFooterVisible = headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Always + || headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Auto && headerContext.Grid.GetTotalSummaryItems().Count > 0; + string footerItemText = isFooterVisible ? "Hide Footer" : "Show Footer"; + var newFooterState = isFooterVisible ? GridFooterDisplayMode.Never : GridFooterDisplayMode.Always; + args.Items.AddCustomItem(footerItemText, () => { + headerContext.Grid.BeginUpdate(); + headerContext.Grid.FooterDisplayMode = newFooterState; + headerContext.Grid.EndUpdate(); + }); + } } @@ -118,28 +154,22 @@ } } - async Task NewItem_Click() - { + async Task NewItem_Click() { await Grid.StartEditNewRowAsync(); } - void ColumnChooserItem_Click(ToolbarItemClickEventArgs e) - { + void ColumnChooserItem_Click(ToolbarItemClickEventArgs e) { Grid.ShowColumnChooser(); } - async Task ExportXlsxItem_Click() - { + async Task ExportXlsxItem_Click() { await Grid.ExportToXlsxAsync(ExportFileName); } - async Task ExportXlsItem_Click() - { + async Task ExportXlsItem_Click() { await Grid.ExportToXlsAsync(ExportFileName); } - async Task ExportCsvItem_Click() - { + async Task ExportCsvItem_Click() { await Grid.ExportToCsvAsync(ExportFileName); } - async Task ExportPdfItem_Click() - { + async Task ExportPdfItem_Click() { await Grid.ExportToPdfAsync(ExportFileName); } } \ No newline at end of file From 45d10940e168766f7d53c595e440811c5a33e6f3 Mon Sep 17 00:00:00 2001 From: iancaringal-devexpress Date: Mon, 20 Apr 2026 15:47:36 +0800 Subject: [PATCH 4/9] Updated column context menu to custom context menu --- .../Data/GridContextMenuHelper.cs | 105 ++++-------------- .../Pages/GridContextMenuContainer.razor | 20 ++-- CS/GridWithContextMenu/Pages/Index.razor | 2 +- 3 files changed, 30 insertions(+), 97 deletions(-) diff --git a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs index 4d8c591..7f6789a 100644 --- a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs +++ b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs @@ -3,9 +3,8 @@ namespace GridWithContextMenu.Data { public enum GridContextMenuItemType { FullExpand, FullCollapse, - SortAscending, SortDescending, ClearSorting, - GroupByColumn, UngroupColumn, ClearGrouping, ShowGroupPanel, - HideColumn, ShowColumnChooser, + ShowGroupPanel, + ShowColumnChooser, ClearFilter, ShowFilterRow, ShowFooter, @@ -13,9 +12,9 @@ public enum GridContextMenuItemType { ExpandDetailRow, CollapseDetailRow, NewRow, EditRow, DeleteRow, - FixColumnToRight, FixColumnToLeft, Unfix, + SaveUpdates, CancelUpdates, - SaveUpdates, CancelUpdates + ExportXls, ExportXlsx, ExportPdf, ExportDocx } public class ContextMenuItem { @@ -29,7 +28,7 @@ public class ContextMenuItem { } public class GridContextMenuHelper { - static List CreateColumnContextMenuItems() { + static List CreateCustomContextMenuItems() { return new List { new ContextMenuItem { ItemType = GridContextMenuItemType.FullExpand, Text = "Expand All", IconCssClass="grid-context-menu-item-full-expand" }, new ContextMenuItem { ItemType = GridContextMenuItemType.FullCollapse, Text = "Collapse All", IconCssClass="grid-context-menu-item-full-collapse" }, @@ -59,9 +58,9 @@ public static bool IsContextMenuElement(GridElementType elementType) { } public static bool IsCustomContextMenuElement(GridElementType elementType) { switch(elementType) { - //case GridElementType.ToolbarContainer: - //case GridElementType.PagerContainer: - // return true; + case GridElementType.ToolbarContainer: + case GridElementType.PagerContainer: + return true; } return false; } @@ -73,8 +72,7 @@ public static bool IsRowContextMenuElement(GridElementType elementType) { return false; } - public static void ProcessColumnMenuItemClick(ContextMenuItem item, IGridColumn column, IGrid grid) { - var dataColumn = column as IGridDataColumn; + public static void ProcessCustomMenuItemClick(ContextMenuItem item, IGrid grid) { grid.BeginUpdate(); switch(item.ItemType) { case GridContextMenuItemType.FullExpand: @@ -134,19 +132,19 @@ public static async Task ProcessRowMenuItemClickAsync(ContextMenuItem item, int break; } } - public static List GetColumnItems(GridCustomizeElementEventArgs e) { - var items = CreateColumnContextMenuItems(); + public static List GetCustomItems(GridCustomizeElementEventArgs e) { + var items = CreateCustomContextMenuItems(); var applyBeginGroupForNextVisibleItem = false; foreach(var item in items) { - item.Visible = IsColumnMenuItemVisible(e, item.ItemType); + item.Visible = IsCustomMenuItemVisible(e, item.ItemType); if(!item.Visible && item.BeginGroup) applyBeginGroupForNextVisibleItem = true; if(item.Visible && applyBeginGroupForNextVisibleItem) { item.BeginGroup = true; applyBeginGroupForNextVisibleItem = false; } - item.Enabled = IsColumnMenuItemEnabled(e, item.ItemType); - var isSelected = IsColumnMenuItemSelected(e, item.ItemType); + item.Enabled = IsCustomMenuItemEnabled(e, item.ItemType); + var isSelected = IsCustomMenuItemSelected(e, item.ItemType); if(item.Enabled && isSelected) item.CssClass = "menu-item-selected"; } @@ -161,58 +159,22 @@ public static List GetRowItems(GridCustomizeElementEventArgs e) return items; } - static bool IsColumnMenuItemVisible(GridCustomizeElementEventArgs e, GridContextMenuItemType itemType) { - var dataColumn = e.Column as IGridDataColumn; - var allowSort = GetAllowSort(e.Column, e.Grid); - var allowGroup = GetAllowGroup(e.Column, e.Grid); + static bool IsCustomMenuItemVisible(GridCustomizeElementEventArgs e, GridContextMenuItemType itemType) { + switch(itemType) { case GridContextMenuItemType.FullExpand: - case GridContextMenuItemType.FullCollapse: - return e.ElementType == GridElementType.GroupPanelHeader; - case GridContextMenuItemType.SortAscending: - case GridContextMenuItemType.SortDescending: - return allowSort; - case GridContextMenuItemType.ClearSorting: - return allowSort && dataColumn.GroupIndex < 0; - case GridContextMenuItemType.GroupByColumn: - return allowGroup && dataColumn.GroupIndex < 0; - case GridContextMenuItemType.UngroupColumn: - return allowGroup && dataColumn.GroupIndex > -1; - case GridContextMenuItemType.ClearGrouping: - return e.Grid.AllowGroup; + case GridContextMenuItemType.FullCollapse: case GridContextMenuItemType.ShowGroupPanel: case GridContextMenuItemType.ShowFilterRow: case GridContextMenuItemType.ShowFooter: - case GridContextMenuItemType.HideColumn: case GridContextMenuItemType.ShowColumnChooser: - case GridContextMenuItemType.FixColumnToLeft: - case GridContextMenuItemType.FixColumnToRight: - case GridContextMenuItemType.Unfix: case GridContextMenuItemType.ClearFilter: return true; } return false; } - static bool IsColumnMenuItemSelected(GridCustomizeElementEventArgs e, GridContextMenuItemType itemType) { - var dataColumn = e.Column as IGridDataColumn; - var isSorted = dataColumn != null && dataColumn.SortIndex > -1; - var isGrouped = dataColumn != null && dataColumn.GroupIndex > -1; - var sortOrder = GridColumnSortOrder.None; - var fixedPosition = dataColumn.FixedPosition; - if (isSorted || isGrouped) { - sortOrder = dataColumn.SortOrder; - if (sortOrder == GridColumnSortOrder.None) - sortOrder = GridColumnSortOrder.Ascending; - } + static bool IsCustomMenuItemSelected(GridCustomizeElementEventArgs e, GridContextMenuItemType itemType) { switch(itemType) { - case GridContextMenuItemType.SortAscending: - return sortOrder == GridColumnSortOrder.Ascending; - case GridContextMenuItemType.SortDescending: - return sortOrder == GridColumnSortOrder.Descending; - case GridContextMenuItemType.FixColumnToLeft: - return fixedPosition == GridColumnFixedPosition.Left; - case GridContextMenuItemType.FixColumnToRight: - return fixedPosition == GridColumnFixedPosition.Right; case GridContextMenuItemType.ShowGroupPanel: return e.Grid.ShowGroupPanel; case GridContextMenuItemType.ShowFilterRow: @@ -223,33 +185,17 @@ static bool IsColumnMenuItemSelected(GridCustomizeElementEventArgs e, GridContex } return false; } - static bool IsColumnMenuItemEnabled(GridCustomizeElementEventArgs e, GridContextMenuItemType itemType) { - var dataColumn = e.Column as IGridDataColumn; - var allowSort = GetAllowSort(e.Column, e.Grid); - var allowGroup = GetAllowGroup(e.Column, e.Grid); + static bool IsCustomMenuItemEnabled(GridCustomizeElementEventArgs e, GridContextMenuItemType itemType) { switch(itemType) { case GridContextMenuItemType.FullExpand: case GridContextMenuItemType.FullCollapse: - case GridContextMenuItemType.SortAscending: - case GridContextMenuItemType.SortDescending: - case GridContextMenuItemType.GroupByColumn: - case GridContextMenuItemType.UngroupColumn: case GridContextMenuItemType.ShowGroupPanel: case GridContextMenuItemType.ShowFilterRow: case GridContextMenuItemType.ShowFooter: - case GridContextMenuItemType.HideColumn: case GridContextMenuItemType.ShowColumnChooser: - case GridContextMenuItemType.FixColumnToLeft: - case GridContextMenuItemType.FixColumnToRight: return true; - case GridContextMenuItemType.ClearSorting: - return allowSort && (dataColumn.SortIndex > -1 || dataColumn.GroupIndex > -1); - case GridContextMenuItemType.ClearGrouping: - return e.Grid.AllowGroup && e.Grid.GetGroupCount() > 1; case GridContextMenuItemType.ClearFilter: - return e.Grid.GetDataColumns().Any(i => i.FilterRowValue != null); - case GridContextMenuItemType.Unfix: - return e.Column.FixedPosition != GridColumnFixedPosition.None; + return e.Grid.GetFilterCriteria() != null ? true : false; } return false; } @@ -305,16 +251,5 @@ static bool IsRowMenuItemEnabled(GridCustomizeElementEventArgs e, GridContextMen } return false; } - - static bool GetAllowSort(IGridColumn column, IGrid grid) { - if(column is IGridDataColumn dataColumn) - return dataColumn.AllowSort ?? grid.AllowSort; - return false; - } - static bool GetAllowGroup(IGridColumn column, IGrid grid) { - if(column is IGridDataColumn dataColumn) - return dataColumn.AllowGroup ?? grid.AllowGroup; - return false; - } } } diff --git a/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor b/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor index e0fed7a..e6ca277 100644 --- a/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor +++ b/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor @@ -1,9 +1,9 @@ @using GridWithContextMenu.Data @using System.Collections - + @code { - DxContextMenu ColumnContextMenu { get; set; } + DxContextMenu CustomContextMenu { get; set; } DxContextMenu RowContextMenu { get; set; } - IEnumerable ColumnContextMenuData { get; set; } + IEnumerable CustomContextMenuData { get; set; } IEnumerable RowContextMenuData { get; set; } - IGridColumn ContextMenuColumn { get; set; } int ContextMenuRowIndex { get; set; } [Parameter] public IGrid Grid { get; set; } - void ColumnContextMenu_ItemClick(ContextMenuItemClickEventArgs e) - => GridContextMenuHelper.ProcessColumnMenuItemClick((ContextMenuItem)e.ItemInfo.DataItem, ContextMenuColumn, Grid); + void CustomContextMenu_ItemClick(ContextMenuItemClickEventArgs e) + => GridContextMenuHelper.ProcessCustomMenuItemClick((ContextMenuItem)e.ItemInfo.DataItem, Grid); async Task RowContextMenu_ItemClick(ContextMenuItemClickEventArgs e) => await GridContextMenuHelper.ProcessRowMenuItemClickAsync((ContextMenuItem)e.ItemInfo.DataItem, ContextMenuRowIndex, Grid); public async Task Grid_ContextMenu(GridCustomizeElementEventArgs e, MouseEventArgs mouseArgs) { if(GridContextMenuHelper.IsCustomContextMenuElement(e.ElementType)) { - ContextMenuColumn = e.Column; - ColumnContextMenuData = GridContextMenuHelper.GetColumnItems(e); - await ColumnContextMenu.ShowAsync(mouseArgs); + CustomContextMenuData = GridContextMenuHelper.GetCustomItems(e); + await CustomContextMenu.ShowAsync(mouseArgs); } if(GridContextMenuHelper.IsRowContextMenuElement(e.ElementType)) { ContextMenuRowIndex = e.VisibleIndex; diff --git a/CS/GridWithContextMenu/Pages/Index.razor b/CS/GridWithContextMenu/Pages/Index.razor index b42a1e6..1baf46d 100644 --- a/CS/GridWithContextMenu/Pages/Index.razor +++ b/CS/GridWithContextMenu/Pages/Index.razor @@ -61,7 +61,7 @@ void Grid_CustomizeContextMenu(GridCustomizeContextMenuEventArgs args) { if (args.Context is GridDataRowCommandContext rowContext) { if (rowContext.Grid.IsEditing()) { - args.Items.AddCustomItem("Save", async () => { + var save = args.Items.AddCustomItem("Save", async () => { rowContext.Grid.BeginUpdate(); await rowContext.Grid.SaveChangesAsync(); rowContext.Grid.EndUpdate(); From f8d29aaf1d94644f46854c462c3987f5d4298b8b Mon Sep 17 00:00:00 2001 From: iancaringal-devexpress Date: Mon, 20 Apr 2026 16:44:32 +0800 Subject: [PATCH 5/9] Implement Export option in context menu --- .../Data/GridContextMenuHelper.cs | 38 ++++++++++++++++--- CS/GridWithContextMenu/wwwroot/css/icons.css | 13 +++++-- .../wwwroot/images/icons/export.svg | 4 ++ 3 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 CS/GridWithContextMenu/wwwroot/images/icons/export.svg diff --git a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs index 7f6789a..a1c20fa 100644 --- a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs +++ b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs @@ -14,7 +14,7 @@ public enum GridContextMenuItemType { SaveUpdates, CancelUpdates, - ExportXls, ExportXlsx, ExportPdf, ExportDocx + ExportXls, ExportXlsx, ExportPdf, ExportCsv } public class ContextMenuItem { @@ -36,8 +36,12 @@ static List CreateCustomContextMenuItems() { new ContextMenuItem { ItemType = GridContextMenuItemType.ShowColumnChooser, Text = "Column Chooser", IconCssClass="grid-context-menu-item-column-chooser" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ClearFilter, Text = "Clear Filter", BeginGroup = true, IconCssClass="grid-context-menu-item-clear-filter" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowFilterRow, Text = "Filter Row", IconCssClass="grid-context-menu-item-filter-row" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.ShowFooter, Text = "Footer", IconCssClass="grid-context-menu-item-footer" } - }; + new ContextMenuItem { ItemType = GridContextMenuItemType.ShowFooter, Text = "Footer", IconCssClass="grid-context-menu-item-footer" }, + new ContextMenuItem { ItemType = GridContextMenuItemType.ExportCsv, Text = "Export to CSV", BeginGroup = true, IconCssClass="grid-context-menu-item-export" }, + new ContextMenuItem { ItemType = GridContextMenuItemType.ExportXlsx, Text = "Export to XLSX", IconCssClass="grid-context-menu-item-export" }, + new ContextMenuItem { ItemType = GridContextMenuItemType.ExportXls, Text = "Export to XLS", IconCssClass="grid-context-menu-item-export" }, + new ContextMenuItem { ItemType = GridContextMenuItemType.ExportPdf, Text = "Export to PDF", IconCssClass="grid-context-menu-item-export" }, + }; } static List CreateRowContextMenuItems() { return new List { @@ -73,7 +77,8 @@ public static bool IsRowContextMenuElement(GridElementType elementType) { } public static void ProcessCustomMenuItemClick(ContextMenuItem item, IGrid grid) { - grid.BeginUpdate(); + const string ExportFileName = "ExportResult"; + grid.BeginUpdate(); switch(item.ItemType) { case GridContextMenuItemType.FullExpand: grid.ExpandAllGroupRows(); @@ -98,7 +103,19 @@ public static void ProcessCustomMenuItemClick(ContextMenuItem item, IGrid grid) case GridContextMenuItemType.ClearFilter: grid.ClearFilter(); break; - } + case GridContextMenuItemType.ExportCsv: + grid.ExportToCsvAsync(ExportFileName); + break; + case GridContextMenuItemType.ExportXlsx: + grid.ExportToXlsxAsync(ExportFileName); + break; + case GridContextMenuItemType.ExportXls: + grid.ExportToXlsAsync(ExportFileName); + break; + case GridContextMenuItemType.ExportPdf: + grid.ExportToPdfAsync(ExportFileName); + break; + } grid.EndUpdate(); } public static async Task ProcessRowMenuItemClickAsync(ContextMenuItem item, int visibleIndex, IGrid grid) { @@ -170,6 +187,11 @@ static bool IsCustomMenuItemVisible(GridCustomizeElementEventArgs e, GridContext case GridContextMenuItemType.ShowColumnChooser: case GridContextMenuItemType.ClearFilter: return true; + case GridContextMenuItemType.ExportCsv: + case GridContextMenuItemType.ExportXlsx: + case GridContextMenuItemType.ExportXls: + case GridContextMenuItemType.ExportPdf: + return e.ElementType == GridElementType.ToolbarContainer; } return false; } @@ -193,7 +215,11 @@ static bool IsCustomMenuItemEnabled(GridCustomizeElementEventArgs e, GridContext case GridContextMenuItemType.ShowFilterRow: case GridContextMenuItemType.ShowFooter: case GridContextMenuItemType.ShowColumnChooser: - return true; + case GridContextMenuItemType.ExportCsv: + case GridContextMenuItemType.ExportXlsx: + case GridContextMenuItemType.ExportXls: + case GridContextMenuItemType.ExportPdf: + return true; case GridContextMenuItemType.ClearFilter: return e.Grid.GetFilterCriteria() != null ? true : false; } diff --git a/CS/GridWithContextMenu/wwwroot/css/icons.css b/CS/GridWithContextMenu/wwwroot/css/icons.css index 9b65aef..1204308 100644 --- a/CS/GridWithContextMenu/wwwroot/css/icons.css +++ b/CS/GridWithContextMenu/wwwroot/css/icons.css @@ -31,7 +31,8 @@ .grid-context-menu-item-collapse-detail-row, .grid-context-menu-item-new-row, .grid-context-menu-item-edit-row, -.grid-context-menu-item-delete-row { +.grid-context-menu-item-delete-row, +.grid-context-menu-item-export { width: 16px; height: 16px; background-repeat: no-repeat; @@ -58,7 +59,8 @@ .dropdown-item:active .grid-context-menu-item-collapse-detail-row, .dropdown-item:active .grid-context-menu-item-new-row, .dropdown-item:active .grid-context-menu-item-edit-row, -.dropdown-item:active .grid-context-menu-item-delete-row { +.dropdown-item:active .grid-context-menu-item-delete-row, +.dropdown-item:active .grid-context-menu-item-export { background-color: white; } @@ -78,7 +80,8 @@ .dropdown-item.disabled .grid-context-menu-item-collapse-detail-row, .dropdown-item.disabled .grid-context-menu-item-new-row, .dropdown-item.disabled .grid-context-menu-item-edit-row, -.dropdown-item.disabled .grid-context-menu-item-delete-row { +.dropdown-item.disabled .grid-context-menu-item-delete-row, +.dropdown-item.disabled .grid-context-menu-item-export { background-color: #c3c2c2; } @@ -166,6 +169,10 @@ mask-image: url(../images/icons/delete-row.svg); -webkit-mask-image: url(../images/icons/delete-row.svg); } +.grid-context-menu-item-export { + mask-image: url(../images/icons/export.svg); + -webkit-mask-image: url(../images/icons/export.svg); +} .grid-context-menu-item-filter-row, diff --git a/CS/GridWithContextMenu/wwwroot/images/icons/export.svg b/CS/GridWithContextMenu/wwwroot/images/icons/export.svg new file mode 100644 index 0000000..d8292c2 --- /dev/null +++ b/CS/GridWithContextMenu/wwwroot/images/icons/export.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 1c9fb2f2fb43a58d560474ae79620b62597c45b7 Mon Sep 17 00:00:00 2001 From: iancaringal-devexpress Date: Thu, 23 Apr 2026 11:33:52 +0800 Subject: [PATCH 6/9] convert custom click to async function --- .../Data/GridContextMenuHelper.cs | 20 ++++++++++++------- .../Pages/GridContextMenuContainer.razor | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs index a1c20fa..79b8ef1 100644 --- a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs +++ b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs @@ -30,7 +30,8 @@ public class ContextMenuItem { public class GridContextMenuHelper { static List CreateCustomContextMenuItems() { return new List { - new ContextMenuItem { ItemType = GridContextMenuItemType.FullExpand, Text = "Expand All", IconCssClass="grid-context-menu-item-full-expand" }, + new ContextMenuItem { ItemType = GridContextMenuItemType.NewRow, Text = "New", BeginGroup = true, IconCssClass="grid-context-menu-item-new-row" }, + new ContextMenuItem { ItemType = GridContextMenuItemType.FullExpand, Text = "Expand All", IconCssClass="grid-context-menu-item-full-expand" }, new ContextMenuItem { ItemType = GridContextMenuItemType.FullCollapse, Text = "Collapse All", IconCssClass="grid-context-menu-item-full-collapse" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowGroupPanel, Text = "Group Panel", IconCssClass="grid-context-menu-item-show-group-panel" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowColumnChooser, Text = "Column Chooser", IconCssClass="grid-context-menu-item-column-chooser" }, @@ -76,11 +77,14 @@ public static bool IsRowContextMenuElement(GridElementType elementType) { return false; } - public static void ProcessCustomMenuItemClick(ContextMenuItem item, IGrid grid) { + public static async Task ProcessCustomMenuItemClick(ContextMenuItem item, IGrid grid) { const string ExportFileName = "ExportResult"; grid.BeginUpdate(); switch(item.ItemType) { - case GridContextMenuItemType.FullExpand: + case GridContextMenuItemType.NewRow: + await grid.StartEditNewRowAsync(); + break; + case GridContextMenuItemType.FullExpand: grid.ExpandAllGroupRows(); break; case GridContextMenuItemType.FullCollapse: @@ -104,16 +108,16 @@ public static void ProcessCustomMenuItemClick(ContextMenuItem item, IGrid grid) grid.ClearFilter(); break; case GridContextMenuItemType.ExportCsv: - grid.ExportToCsvAsync(ExportFileName); + await grid.ExportToCsvAsync(ExportFileName); break; case GridContextMenuItemType.ExportXlsx: - grid.ExportToXlsxAsync(ExportFileName); + await grid.ExportToXlsxAsync(ExportFileName); break; case GridContextMenuItemType.ExportXls: - grid.ExportToXlsAsync(ExportFileName); + await grid.ExportToXlsAsync(ExportFileName); break; case GridContextMenuItemType.ExportPdf: - grid.ExportToPdfAsync(ExportFileName); + await grid.ExportToPdfAsync(ExportFileName); break; } grid.EndUpdate(); @@ -187,6 +191,7 @@ static bool IsCustomMenuItemVisible(GridCustomizeElementEventArgs e, GridContext case GridContextMenuItemType.ShowColumnChooser: case GridContextMenuItemType.ClearFilter: return true; + case GridContextMenuItemType.NewRow: case GridContextMenuItemType.ExportCsv: case GridContextMenuItemType.ExportXlsx: case GridContextMenuItemType.ExportXls: @@ -209,6 +214,7 @@ static bool IsCustomMenuItemSelected(GridCustomizeElementEventArgs e, GridContex } static bool IsCustomMenuItemEnabled(GridCustomizeElementEventArgs e, GridContextMenuItemType itemType) { switch(itemType) { + case GridContextMenuItemType.NewRow: case GridContextMenuItemType.FullExpand: case GridContextMenuItemType.FullCollapse: case GridContextMenuItemType.ShowGroupPanel: diff --git a/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor b/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor index e6ca277..7c69bfc 100644 --- a/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor +++ b/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor @@ -38,8 +38,8 @@ [Parameter] public IGrid Grid { get; set; } - void CustomContextMenu_ItemClick(ContextMenuItemClickEventArgs e) - => GridContextMenuHelper.ProcessCustomMenuItemClick((ContextMenuItem)e.ItemInfo.DataItem, Grid); + async Task CustomContextMenu_ItemClick(ContextMenuItemClickEventArgs e) + => await GridContextMenuHelper.ProcessCustomMenuItemClick((ContextMenuItem)e.ItemInfo.DataItem, Grid); async Task RowContextMenu_ItemClick(ContextMenuItemClickEventArgs e) => await GridContextMenuHelper.ProcessRowMenuItemClickAsync((ContextMenuItem)e.ItemInfo.DataItem, ContextMenuRowIndex, Grid); From 932cd7df587140f9222bb504ec873ee75a3df035 Mon Sep 17 00:00:00 2001 From: iancaringal-devexpress Date: Mon, 27 Apr 2026 15:50:59 +0800 Subject: [PATCH 7/9] add icons and footer menu --- .../Data/GridContextMenuHelper.cs | 4 +- CS/GridWithContextMenu/Pages/Index.razor | 76 ++++++++++++++----- CS/GridWithContextMenu/wwwroot/css/icons.css | 4 +- .../wwwroot/images/icons/export-grid.svg | 8 ++ .../wwwroot/images/icons/export.svg | 4 - 5 files changed, 67 insertions(+), 29 deletions(-) create mode 100644 CS/GridWithContextMenu/wwwroot/images/icons/export-grid.svg delete mode 100644 CS/GridWithContextMenu/wwwroot/images/icons/export.svg diff --git a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs index 79b8ef1..1cb7eed 100644 --- a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs +++ b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs @@ -35,8 +35,8 @@ static List CreateCustomContextMenuItems() { new ContextMenuItem { ItemType = GridContextMenuItemType.FullCollapse, Text = "Collapse All", IconCssClass="grid-context-menu-item-full-collapse" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowGroupPanel, Text = "Group Panel", IconCssClass="grid-context-menu-item-show-group-panel" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowColumnChooser, Text = "Column Chooser", IconCssClass="grid-context-menu-item-column-chooser" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.ClearFilter, Text = "Clear Filter", BeginGroup = true, IconCssClass="grid-context-menu-item-clear-filter" }, - new ContextMenuItem { ItemType = GridContextMenuItemType.ShowFilterRow, Text = "Filter Row", IconCssClass="grid-context-menu-item-filter-row" }, + new ContextMenuItem { ItemType = GridContextMenuItemType.ShowFilterRow, Text = "Filter Row", BeginGroup = true, IconCssClass="grid-context-menu-item-filter-row" }, + new ContextMenuItem { ItemType = GridContextMenuItemType.ClearFilter, Text = "Clear Filter", IconCssClass="grid-context-menu-item-clear-filter" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ShowFooter, Text = "Footer", IconCssClass="grid-context-menu-item-footer" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ExportCsv, Text = "Export to CSV", BeginGroup = true, IconCssClass="grid-context-menu-item-export" }, new ContextMenuItem { ItemType = GridContextMenuItemType.ExportXlsx, Text = "Export to XLSX", IconCssClass="grid-context-menu-item-export" }, diff --git a/CS/GridWithContextMenu/Pages/Index.razor b/CS/GridWithContextMenu/Pages/Index.razor index 1baf46d..68c589a 100644 --- a/CS/GridWithContextMenu/Pages/Index.razor +++ b/CS/GridWithContextMenu/Pages/Index.razor @@ -61,76 +61,110 @@ void Grid_CustomizeContextMenu(GridCustomizeContextMenuEventArgs args) { if (args.Context is GridDataRowCommandContext rowContext) { if (rowContext.Grid.IsEditing()) { - var save = args.Items.AddCustomItem("Save", async () => { + var saveEdit = args.Items.AddCustomItem("Save", async () => { rowContext.Grid.BeginUpdate(); await rowContext.Grid.SaveChangesAsync(); rowContext.Grid.EndUpdate(); }); - args.Items.AddCustomItem("Cancel", async () => { + saveEdit.IconCssClass = "grid-context-menu-item-edit-row"; + + var cancelEdit = args.Items.AddCustomItem("Cancel", async () => { rowContext.Grid.BeginUpdate(); await rowContext.Grid.CancelEditAsync(); rowContext.Grid.EndUpdate(); }); + cancelEdit.IconCssClass = "grid-context-menu-item-delete-row"; } - args.Items.AddCustomItem("New", async () => { + var newRow = args.Items.AddCustomItem("New", async () => { rowContext.Grid.BeginUpdate(); await rowContext.Grid.StartEditNewRowAsync(); rowContext.Grid.EndUpdate(); - }).BeginGroup = true; - args.Items.AddCustomItem("Edit", async () => { + }); + newRow.IconCssClass = "grid-context-menu-item-new-row"; + newRow.BeginGroup = true; + + var editRow = args.Items.AddCustomItem("Edit", async () => { rowContext.Grid.BeginUpdate(); await rowContext.Grid.StartEditRowAsync(rowContext.RowVisibleIndex); rowContext.Grid.EndUpdate(); }); - args.Items.AddCustomItem("Delete", async () => { + editRow.IconCssClass = "grid-context-menu-item-edit-row"; + + var deleteRow = args.Items.AddCustomItem("Delete", () => { rowContext.Grid.BeginUpdate(); rowContext.Grid.ShowRowDeleteConfirmation(rowContext.RowVisibleIndex); rowContext.Grid.EndUpdate(); }); + deleteRow.IconCssClass = "grid-context-menu-item-delete-row"; } if (args.Context is GridHeaderCommandContext headerContext) { var isFilterRowVisible = headerContext.Grid.ShowFilterRow != false; - string filterRowItemText = isFilterRowVisible ? "Hide Filter Row" : "Show Filter Row"; var newFilterRowState = isFilterRowVisible ? false : true; - args.Items.AddCustomItem(filterRowItemText, () => { + var filterRow = args.Items.AddCustomItem("Filter Row", () => { headerContext.Grid.BeginUpdate(); headerContext.Grid.ShowFilterRow = newFilterRowState; headerContext.Grid.EndUpdate(); }); + filterRow.IconCssClass = "grid-context-menu-item-filter-row"; + filterRow.CssClass = isFilterRowVisible ? "menu-item-selected" : ""; var isFiltered = headerContext.Grid.GetFilterCriteria() != null; - args.Items.AddCustomItem("Clear Filter", () => { + var clearFilter = args.Items.AddCustomItem("Clear Filter", () => { headerContext.Grid.BeginUpdate(); headerContext.Grid.ClearFilter(); headerContext.Grid.EndUpdate(); - }).Enabled = isFiltered ? true : false; + }); + clearFilter.IconCssClass = "grid-context-menu-item-clear-filter"; + clearFilter.Enabled = isFiltered ? true : false; + + var isFooterVisible = headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Always + || headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Auto && headerContext.Grid.GetTotalSummaryItems().Count > 0; + var newFooterState = isFooterVisible ? GridFooterDisplayMode.Never : GridFooterDisplayMode.Always; + var footer = args.Items.AddCustomItem("Footer", () => + { + headerContext.Grid.BeginUpdate(); + headerContext.Grid.FooterDisplayMode = newFooterState; + headerContext.Grid.EndUpdate(); + }); + footer.IconCssClass = "grid-context-menu-item-footer"; + footer.CssClass = isFooterVisible ? "menu-item-selected" : ""; - args.Items.AddCustomItem("Fix Column to the Left", () => { + var fixLeft = args.Items.AddCustomItem("Fix Column to the Left", () => { headerContext.Grid.BeginUpdate(); headerContext.Column.FixedPosition = GridColumnFixedPosition.Left; headerContext.Grid.EndUpdate(); - }).BeginGroup = true; - args.Items.AddCustomItem("Fix Column to the Right", () => { + }); + fixLeft.IconCssClass = "grid-context-menu-item-fix-column-left"; + fixLeft.BeginGroup = true; + + var fixRight = args.Items.AddCustomItem("Fix Column to the Right", () => { headerContext.Grid.BeginUpdate(); headerContext.Column.FixedPosition = GridColumnFixedPosition.Right; headerContext.Grid.EndUpdate(); }); - args.Items.AddCustomItem("Unfix Column", () => { + fixRight.IconCssClass = "grid-context-menu-item-fix-column-right"; + + var unfix = args.Items.AddCustomItem("Unfix Column", () => { headerContext.Grid.BeginUpdate(); headerContext.Column.FixedPosition = GridColumnFixedPosition.None; headerContext.Grid.EndUpdate(); }); + unfix.IconCssClass = "grid-context-menu-item-unfix-column"; + } - var isFooterVisible = headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Always - || headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Auto && headerContext.Grid.GetTotalSummaryItems().Count > 0; - string footerItemText = isFooterVisible ? "Hide Footer" : "Show Footer"; + if (args.Context is GridFooterCommandContext footerContext) { + var isFooterVisible = footerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Always + || footerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Auto && footerContext.Grid.GetTotalSummaryItems().Count > 0; var newFooterState = isFooterVisible ? GridFooterDisplayMode.Never : GridFooterDisplayMode.Always; - args.Items.AddCustomItem(footerItemText, () => { - headerContext.Grid.BeginUpdate(); - headerContext.Grid.FooterDisplayMode = newFooterState; - headerContext.Grid.EndUpdate(); + var footer = args.Items.AddCustomItem("Footer", () => + { + footerContext.Grid.BeginUpdate(); + footerContext.Grid.FooterDisplayMode = newFooterState; + footerContext.Grid.EndUpdate(); }); + footer.IconCssClass = "grid-context-menu-item-footer"; + footer.CssClass = isFooterVisible ? "menu-item-selected" : ""; } } diff --git a/CS/GridWithContextMenu/wwwroot/css/icons.css b/CS/GridWithContextMenu/wwwroot/css/icons.css index 1204308..c313445 100644 --- a/CS/GridWithContextMenu/wwwroot/css/icons.css +++ b/CS/GridWithContextMenu/wwwroot/css/icons.css @@ -170,8 +170,8 @@ -webkit-mask-image: url(../images/icons/delete-row.svg); } .grid-context-menu-item-export { - mask-image: url(../images/icons/export.svg); - -webkit-mask-image: url(../images/icons/export.svg); + mask-image: url(../images/icons/export-grid.svg); + -webkit-mask-image: url(../images/icons/export-grid.svg); } diff --git a/CS/GridWithContextMenu/wwwroot/images/icons/export-grid.svg b/CS/GridWithContextMenu/wwwroot/images/icons/export-grid.svg new file mode 100644 index 0000000..13c6494 --- /dev/null +++ b/CS/GridWithContextMenu/wwwroot/images/icons/export-grid.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/CS/GridWithContextMenu/wwwroot/images/icons/export.svg b/CS/GridWithContextMenu/wwwroot/images/icons/export.svg deleted file mode 100644 index d8292c2..0000000 --- a/CS/GridWithContextMenu/wwwroot/images/icons/export.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file From b8d114e939733e6f7bda597517991767a2e9992d Mon Sep 17 00:00:00 2001 From: DevExpressExampleBot Date: Mon, 27 Apr 2026 18:07:54 +0400 Subject: [PATCH 8/9] README auto update [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a89a5c4..0ec1054 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -![](https://img.shields.io/endpoint?url=https://codecentral.devexpress.com/api/v1/VersionRange/520791644/25.1.3%2B) +![](https://img.shields.io/endpoint?url=https://codecentral.devexpress.com/api/v1/VersionRange/520791644/25.2.5%2B) [![](https://img.shields.io/badge/Open_in_DevExpress_Support_Center-FF7200?style=flat-square&logo=DevExpress&logoColor=white)](https://supportcenter.devexpress.com/ticket/details/T1106945) [![](https://img.shields.io/badge/📖_How_to_use_DevExpress_Examples-e9f6fc?style=flat-square)](https://docs.devexpress.com/GeneralInformation/403183) [![](https://img.shields.io/badge/💬_Leave_Feedback-feecdd?style=flat-square)](#does-this-example-address-your-development-requirementsobjectives) From 53c6d9b92f9427a0994484838322da66bbb882df Mon Sep 17 00:00:00 2001 From: iancaringal-devexpress Date: Thu, 30 Apr 2026 15:34:17 +0800 Subject: [PATCH 9/9] refactored Grid_CustomizeContextMenu() --- .../Data/GridContextMenuHelper.cs | 109 ++++++++++++++ CS/GridWithContextMenu/Pages/Index.razor | 134 +----------------- 2 files changed, 116 insertions(+), 127 deletions(-) diff --git a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs index 1cb7eed..7e69d8e 100644 --- a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs +++ b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs @@ -283,5 +283,114 @@ static bool IsRowMenuItemEnabled(GridCustomizeElementEventArgs e, GridContextMen } return false; } + + public static void CustomizeContextMenu(GridCustomizeContextMenuEventArgs args) { + if (args.Context is GridDataRowCommandContext rowContext) AddRowItems(args, rowContext); + + if (args.Context is GridHeaderCommandContext headerContext) AddHeaderItems(args, headerContext); + + if (args.Context is GridFooterCommandContext footerContext) AddFooterItems(args, footerContext); + } + + private static void AddRowItems(GridCustomizeContextMenuEventArgs args, GridDataRowCommandContext rowContext) { + var update = (IGridCommandContext c, Action t) => { + c.Grid.BeginUpdate(); + t(); + c.Grid.EndUpdate(); + }; + var updateAsync = async (IGridCommandContext c, Task t) => { + c.Grid.BeginUpdate(); + await t; + c.Grid.EndUpdate(); + }; + + if (rowContext.Grid.IsEditing()) { + var saveEdit = args.Items.AddCustomItem("Save", async () => + await updateAsync(rowContext, rowContext.Grid.SaveChangesAsync())); + saveEdit.IconCssClass = "grid-context-menu-item-edit-row"; + + var cancelEdit = args.Items.AddCustomItem("Cancel", async () => + await updateAsync(rowContext, rowContext.Grid.CancelEditAsync())); + cancelEdit.IconCssClass = "grid-context-menu-item-delete-row"; + } + var newRow = args.Items.AddCustomItem("New", async () => + await updateAsync(rowContext, rowContext.Grid.StartEditNewRowAsync())); + newRow.IconCssClass = "grid-context-menu-item-new-row"; + newRow.BeginGroup = true; + + var editRow = args.Items.AddCustomItem("Edit", async () => + await updateAsync(rowContext, rowContext.Grid.StartEditRowAsync(rowContext.RowVisibleIndex))); + editRow.IconCssClass = "grid-context-menu-item-edit-row"; + + var deleteRow = args.Items.AddCustomItem("Delete", () => + update(rowContext, () => rowContext.Grid.ShowRowDeleteConfirmation(rowContext.RowVisibleIndex))); + deleteRow.IconCssClass = "grid-context-menu-item-delete-row"; + } + private static void AddHeaderItems(GridCustomizeContextMenuEventArgs args, GridHeaderCommandContext headerContext) { + var update = (IGridCommandContext c, Action t) => { + c.Grid.BeginUpdate(); + t(); + c.Grid.EndUpdate(); + }; + var updateAsync = async (IGridCommandContext c, Task t) => { + c.Grid.BeginUpdate(); + await t; + c.Grid.EndUpdate(); + }; + + var isFilterRowVisible = headerContext.Grid.ShowFilterRow != false; + var newFilterRowState = isFilterRowVisible ? false : true; + var filterRow = args.Items.AddCustomItem("Filter Row", () => + update(headerContext, () => headerContext.Grid.ShowFilterRow = newFilterRowState)); + filterRow.IconCssClass = "grid-context-menu-item-filter-row"; + filterRow.CssClass = isFilterRowVisible ? "menu-item-selected" : ""; + + var isFiltered = headerContext.Grid.GetFilterCriteria() != null; + var clearFilter = args.Items.AddCustomItem("Clear Filter", () => + update(headerContext, () => headerContext.Grid.ClearFilter())); + clearFilter.IconCssClass = "grid-context-menu-item-clear-filter"; + clearFilter.Enabled = isFiltered ? true : false; + + var isFooterVisible = headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Always + || headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Auto && headerContext.Grid.GetTotalSummaryItems().Count > 0; + var newFooterState = isFooterVisible ? GridFooterDisplayMode.Never : GridFooterDisplayMode.Always; + var footer = args.Items.AddCustomItem("Footer", () => + update(headerContext, () => headerContext.Grid.FooterDisplayMode = newFooterState)); + footer.IconCssClass = "grid-context-menu-item-footer"; + footer.CssClass = isFooterVisible ? "menu-item-selected" : ""; + + var fixLeft = args.Items.AddCustomItem("Fix Column to the Left", () => + update(headerContext, () => headerContext.Column.FixedPosition = GridColumnFixedPosition.Left)); + fixLeft.IconCssClass = "grid-context-menu-item-fix-column-left"; + fixLeft.BeginGroup = true; + + var fixRight = args.Items.AddCustomItem("Fix Column to the Right", () => + update(headerContext, () => headerContext.Column.FixedPosition = GridColumnFixedPosition.Right)); + fixRight.IconCssClass = "grid-context-menu-item-fix-column-right"; + + var unfix = args.Items.AddCustomItem("Unfix Column", () => + update(headerContext, () => headerContext.Column.FixedPosition = GridColumnFixedPosition.None)); + unfix.IconCssClass = "grid-context-menu-item-unfix-column"; + } + private static void AddFooterItems(GridCustomizeContextMenuEventArgs args, GridFooterCommandContext footerContext) { + var update = (IGridCommandContext c, Action t) => { + c.Grid.BeginUpdate(); + t(); + c.Grid.EndUpdate(); + }; + var updateAsync = async (IGridCommandContext c, Task t) => { + c.Grid.BeginUpdate(); + await t; + c.Grid.EndUpdate(); + }; + + var isFooterVisible = footerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Always + || footerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Auto && footerContext.Grid.GetTotalSummaryItems().Count > 0; + var newFooterState = isFooterVisible ? GridFooterDisplayMode.Never : GridFooterDisplayMode.Always; + var footer = args.Items.AddCustomItem("Footer", () => + update(footerContext, () => footerContext.Grid.FooterDisplayMode = newFooterState)); + footer.IconCssClass = "grid-context-menu-item-footer"; + footer.CssClass = isFooterVisible ? "menu-item-selected" : ""; + } } } diff --git a/CS/GridWithContextMenu/Pages/Index.razor b/CS/GridWithContextMenu/Pages/Index.razor index 68c589a..dbf22bb 100644 --- a/CS/GridWithContextMenu/Pages/Index.razor +++ b/CS/GridWithContextMenu/Pages/Index.razor @@ -58,116 +58,8 @@ protected override async Task OnInitializedAsync() { GridData = await ForecastService.GetForecastAsync(); } - void Grid_CustomizeContextMenu(GridCustomizeContextMenuEventArgs args) { - if (args.Context is GridDataRowCommandContext rowContext) { - if (rowContext.Grid.IsEditing()) { - var saveEdit = args.Items.AddCustomItem("Save", async () => { - rowContext.Grid.BeginUpdate(); - await rowContext.Grid.SaveChangesAsync(); - rowContext.Grid.EndUpdate(); - }); - saveEdit.IconCssClass = "grid-context-menu-item-edit-row"; - - var cancelEdit = args.Items.AddCustomItem("Cancel", async () => { - rowContext.Grid.BeginUpdate(); - await rowContext.Grid.CancelEditAsync(); - rowContext.Grid.EndUpdate(); - }); - cancelEdit.IconCssClass = "grid-context-menu-item-delete-row"; - } - var newRow = args.Items.AddCustomItem("New", async () => { - rowContext.Grid.BeginUpdate(); - await rowContext.Grid.StartEditNewRowAsync(); - rowContext.Grid.EndUpdate(); - }); - newRow.IconCssClass = "grid-context-menu-item-new-row"; - newRow.BeginGroup = true; - - var editRow = args.Items.AddCustomItem("Edit", async () => { - rowContext.Grid.BeginUpdate(); - await rowContext.Grid.StartEditRowAsync(rowContext.RowVisibleIndex); - rowContext.Grid.EndUpdate(); - }); - editRow.IconCssClass = "grid-context-menu-item-edit-row"; - - var deleteRow = args.Items.AddCustomItem("Delete", () => { - rowContext.Grid.BeginUpdate(); - rowContext.Grid.ShowRowDeleteConfirmation(rowContext.RowVisibleIndex); - rowContext.Grid.EndUpdate(); - }); - deleteRow.IconCssClass = "grid-context-menu-item-delete-row"; - } - - if (args.Context is GridHeaderCommandContext headerContext) { - var isFilterRowVisible = headerContext.Grid.ShowFilterRow != false; - var newFilterRowState = isFilterRowVisible ? false : true; - var filterRow = args.Items.AddCustomItem("Filter Row", () => { - headerContext.Grid.BeginUpdate(); - headerContext.Grid.ShowFilterRow = newFilterRowState; - headerContext.Grid.EndUpdate(); - }); - filterRow.IconCssClass = "grid-context-menu-item-filter-row"; - filterRow.CssClass = isFilterRowVisible ? "menu-item-selected" : ""; - - var isFiltered = headerContext.Grid.GetFilterCriteria() != null; - var clearFilter = args.Items.AddCustomItem("Clear Filter", () => { - headerContext.Grid.BeginUpdate(); - headerContext.Grid.ClearFilter(); - headerContext.Grid.EndUpdate(); - }); - clearFilter.IconCssClass = "grid-context-menu-item-clear-filter"; - clearFilter.Enabled = isFiltered ? true : false; - - var isFooterVisible = headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Always - || headerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Auto && headerContext.Grid.GetTotalSummaryItems().Count > 0; - var newFooterState = isFooterVisible ? GridFooterDisplayMode.Never : GridFooterDisplayMode.Always; - var footer = args.Items.AddCustomItem("Footer", () => - { - headerContext.Grid.BeginUpdate(); - headerContext.Grid.FooterDisplayMode = newFooterState; - headerContext.Grid.EndUpdate(); - }); - footer.IconCssClass = "grid-context-menu-item-footer"; - footer.CssClass = isFooterVisible ? "menu-item-selected" : ""; - - var fixLeft = args.Items.AddCustomItem("Fix Column to the Left", () => { - headerContext.Grid.BeginUpdate(); - headerContext.Column.FixedPosition = GridColumnFixedPosition.Left; - headerContext.Grid.EndUpdate(); - }); - fixLeft.IconCssClass = "grid-context-menu-item-fix-column-left"; - fixLeft.BeginGroup = true; - - var fixRight = args.Items.AddCustomItem("Fix Column to the Right", () => { - headerContext.Grid.BeginUpdate(); - headerContext.Column.FixedPosition = GridColumnFixedPosition.Right; - headerContext.Grid.EndUpdate(); - }); - fixRight.IconCssClass = "grid-context-menu-item-fix-column-right"; - - var unfix = args.Items.AddCustomItem("Unfix Column", () => { - headerContext.Grid.BeginUpdate(); - headerContext.Column.FixedPosition = GridColumnFixedPosition.None; - headerContext.Grid.EndUpdate(); - }); - unfix.IconCssClass = "grid-context-menu-item-unfix-column"; - } - - if (args.Context is GridFooterCommandContext footerContext) { - var isFooterVisible = footerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Always - || footerContext.Grid.FooterDisplayMode == GridFooterDisplayMode.Auto && footerContext.Grid.GetTotalSummaryItems().Count > 0; - var newFooterState = isFooterVisible ? GridFooterDisplayMode.Never : GridFooterDisplayMode.Always; - var footer = args.Items.AddCustomItem("Footer", () => - { - footerContext.Grid.BeginUpdate(); - footerContext.Grid.FooterDisplayMode = newFooterState; - footerContext.Grid.EndUpdate(); - }); - footer.IconCssClass = "grid-context-menu-item-footer"; - footer.CssClass = isFooterVisible ? "menu-item-selected" : ""; - } - } + void Grid_CustomizeContextMenu(GridCustomizeContextMenuEventArgs args) => GridContextMenuHelper.CustomizeContextMenu(args); void Grid_CustomizeElement(GridCustomizeElementEventArgs e) { if(GridContextMenuHelper.IsContextMenuElement(e.ElementType)) { @@ -188,22 +80,10 @@ } } - async Task NewItem_Click() { - await Grid.StartEditNewRowAsync(); - } - void ColumnChooserItem_Click(ToolbarItemClickEventArgs e) { - Grid.ShowColumnChooser(); - } - async Task ExportXlsxItem_Click() { - await Grid.ExportToXlsxAsync(ExportFileName); - } - async Task ExportXlsItem_Click() { - await Grid.ExportToXlsAsync(ExportFileName); - } - async Task ExportCsvItem_Click() { - await Grid.ExportToCsvAsync(ExportFileName); - } - async Task ExportPdfItem_Click() { - await Grid.ExportToPdfAsync(ExportFileName); - } + async Task NewItem_Click() => await Grid.StartEditNewRowAsync(); + void ColumnChooserItem_Click(ToolbarItemClickEventArgs e) => Grid.ShowColumnChooser(); + async Task ExportXlsxItem_Click() => await Grid.ExportToXlsxAsync(ExportFileName); + async Task ExportXlsItem_Click() => await Grid.ExportToXlsAsync(ExportFileName); + async Task ExportCsvItem_Click() => await Grid.ExportToCsvAsync(ExportFileName); + async Task ExportPdfItem_Click() => await Grid.ExportToPdfAsync(ExportFileName); } \ No newline at end of file