diff --git a/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs b/CS/GridWithContextMenu/Data/GridContextMenuHelper.cs index dd18154..d9cb9b9 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, ExportCsv } public class ContextMenuItem { @@ -29,26 +28,21 @@ 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.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.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" } - }; + 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" }, + 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 { @@ -65,62 +59,37 @@ static List CreateRowContextMenuItems() { } public static bool IsContextMenuElement(GridElementType elementType) { - return IsColumnContextMenuElement(elementType) || 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: + case GridElementType.ToolbarContainer: + case GridElementType.PagerContainer: return true; } return false; } public static bool IsRowContextMenuElement(GridElementType elementType) { switch(elementType) { - case GridElementType.DataRow: - case GridElementType.GroupRow: case GridElementType.EditRow: return true; } return false; } - public static void ProcessColumnMenuItemClick(ContextMenuItem item, IGridColumn column, IGrid grid) { - var dataColumn = column as IGridDataColumn; - grid.BeginUpdate(); + 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: 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; @@ -131,26 +100,26 @@ 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; - } + case GridContextMenuItemType.ExportCsv: + await grid.ExportToCsvAsync(ExportFileName); + break; + case GridContextMenuItemType.ExportXlsx: + await grid.ExportToXlsxAsync(ExportFileName); + break; + case GridContextMenuItemType.ExportXls: + await grid.ExportToXlsAsync(ExportFileName); + break; + case GridContextMenuItemType.ExportPdf: + await grid.ExportToPdfAsync(ExportFileName); + break; + } grid.EndUpdate(); } public static async Task ProcessRowMenuItemClickAsync(ContextMenuItem item, int visibleIndex, IGrid grid) { @@ -184,19 +153,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"; } @@ -211,58 +180,28 @@ 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; + case GridContextMenuItemType.NewRow: + case GridContextMenuItemType.ExportCsv: + case GridContextMenuItemType.ExportXlsx: + case GridContextMenuItemType.ExportXls: + case GridContextMenuItemType.ExportPdf: + return e.ElementType == GridElementType.ToolbarContainer; } 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: @@ -273,33 +212,22 @@ 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.NewRow: 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.ExportCsv: + case GridContextMenuItemType.ExportXlsx: + case GridContextMenuItemType.ExportXls: + case GridContextMenuItemType.ExportPdf: + return true; 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; } @@ -356,15 +284,109 @@ 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; - } - } + 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) { + 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 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 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" : ""; + } + + public static void Update(IGridCommandContext context, Action t) + { + context.Grid.BeginUpdate(); + try + { + t(); + } + finally + { + context.Grid.EndUpdate(); + } + } + + public static async Task UpdateAsync(IGridCommandContext context, Task t) + { + context.Grid.BeginUpdate(); + try + { + await t; + } + finally + { + context.Grid.EndUpdate(); + } + } + } } 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/GridContextMenuContainer.razor b/CS/GridWithContextMenu/Pages/GridContextMenuContainer.razor index 1756045..7c69bfc 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); + 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); public async Task Grid_ContextMenu(GridCustomizeElementEventArgs e, MouseEventArgs mouseArgs) { - if(GridContextMenuHelper.IsColumnContextMenuElement(e.ElementType)) { - ContextMenuColumn = e.Column; - ColumnContextMenuData = GridContextMenuHelper.GetColumnItems(e); - await ColumnContextMenu.ShowAsync(mouseArgs); + if(GridContextMenuHelper.IsCustomContextMenuElement(e.ElementType)) { + 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 fdcf795..dbf22bb 100644 --- a/CS/GridWithContextMenu/Pages/Index.razor +++ b/CS/GridWithContextMenu/Pages/Index.razor @@ -8,14 +8,38 @@ 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" + @oncontextmenu:preventDefault> + + + + + + + + + + + + + + + + + - + - + @@ -28,11 +52,15 @@ 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) => GridContextMenuHelper.CustomizeContextMenu(args); + void Grid_CustomizeElement(GridCustomizeElementEventArgs e) { if(GridContextMenuHelper.IsContextMenuElement(e.ElementType)) { e.Attributes["oncontextmenu"] = EventCallback.Factory.Create( @@ -51,4 +79,11 @@ 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 diff --git a/CS/GridWithContextMenu/Properties/launchSettings.json b/CS/GridWithContextMenu/Properties/launchSettings.json new file mode 100644 index 0000000..e962168 --- /dev/null +++ b/CS/GridWithContextMenu/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "GridWithContextMenu": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:2159;http://localhost:2160" + } + } +} \ No newline at end of file diff --git a/CS/GridWithContextMenu/wwwroot/css/icons.css b/CS/GridWithContextMenu/wwwroot/css/icons.css index 9b65aef..c313445 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-grid.svg); + -webkit-mask-image: url(../images/icons/export-grid.svg); +} .grid-context-menu-item-filter-row, 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/LICENSE b/LICENSE index cd4c9a2..7536adc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,5 @@ -This code example is provided "as is" without warranty of any kind. Developer Express Inc ("DevExpress") disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. +This code example is provided "as is" without warranty of any kind. Developer Express Inc ("DevExpress") disclaims all warranties, +either express or implied, including the warranties of merchantability and fitness for a particular purpose. -For licensing terms and conditions of DevExpress product(s) required for, or associated with the use of this code example, please refer to the applicable End-User License Agreement at https://www.devexpress.com/Support/licensingfaq.xml \ No newline at end of file +For terms and conditions governing use of DevExpress product libraries, including product libraries used in this sample, +please review the applicable DevExpress End-User License Agreement at the following address: https://www.devexpress.com/Support/licensingfaq.xml \ No newline at end of file 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)