Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions CS/GridCustomShortcuts/Components/Layout/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
<DxMenu Orientation="@Orientation.Vertical" CssClass="menu">
<Items>
<DxMenuItem NavigateUrl="/" Text="Home" CssClass="menu-item" IconCssClass="icon home-icon"></DxMenuItem>
<DxMenuItem NavigateUrl="/counter" Text="Counter" CssClass="menu-item" IconCssClass="icon counter-icon"></DxMenuItem>
<DxMenuItem NavigateUrl="/weather" Text="Weather" CssClass="menu-item" IconCssClass="icon weather-icon"></DxMenuItem>
</Items>
</DxMenu>
</div>
27 changes: 0 additions & 27 deletions CS/GridCustomShortcuts/Components/Pages/Counter.razor

This file was deleted.

37 changes: 0 additions & 37 deletions CS/GridCustomShortcuts/Components/Pages/Counter.razor.css

This file was deleted.

27 changes: 15 additions & 12 deletions CS/GridCustomShortcuts/Components/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@
@inject WeatherForecastService ForecastService
@implements IAsyncDisposable

<PageTitle>Blazor Grid Keyboard Shortcuts</PageTitle>
<h1>Weather Forecast</h1>

@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<div @ref="gridWrapper">
<DxGrid @ref="grid" Data="@forecasts"
FocusedRowEnabled="true"
EditMode="GridEditMode.EditCell"
EditModelSaving="OnEditModelSaving"
CssClass="mw-1100" ValidationEnabled=false>
<DxGrid @ref="grid" Data="@forecasts"
FocusedRowEnabled="true"
EditModelSaving="OnEditModelSaving"
CssClass="mw-1100">
<Columns>
<DxGridSelectionColumn />
<DxGridSelectionColumn Width="70px" />
<DxGridDataColumn Caption="Date" FieldName="Date" />
<DxGridDataColumn Caption="Temperature (C)" FieldName="TemperatureC" />
<DxGridDataColumn Caption="Temperature (F)" FieldName="TemperatureF" />
Expand All @@ -28,18 +30,18 @@ else
</DxGrid>
</div>


<DxPopup HeaderText="Forecast Entry"
@bind-Visible="@popupVisible"
BodyText="@("Viewing forecast for " + currentDate)">
<DxPopup HeaderText="@($"Weather Forecast for {selectedForecast?.Date:m}")"
@bind-Visible="@popupVisible">
<p><b>Temperature:</b> @selectedForecast?.TemperatureC °C</p>
<p><b>Summary:</b> @selectedForecast?.Summary</p>
</DxPopup>
}

@code {
private WeatherForecast[]? forecasts;
private bool popupVisible;
private ElementReference gridWrapper;
private DateOnly currentDate;
private WeatherForecast? selectedForecast;
private IGrid grid;
private IJSObjectReference? module;
private DotNetObjectReference<Index>? dotNetHelper;
Expand All @@ -51,7 +53,7 @@ else
if (focusedItem == null)
return;
await grid.SaveChangesAsync();
currentDate = focusedItem.Date;
selectedForecast = focusedItem;
popupVisible = true;
StateHasChanged();
}
Expand All @@ -74,6 +76,7 @@ else
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Components/Pages/Index.razor.js");
dotNetHelper = DotNetObjectReference.Create(this);
await module.InvokeVoidAsync("focusGrid");
await module.InvokeVoidAsync("addCaptureKeyListener", gridWrapper, dotNetHelper);
}
}
Expand Down
4 changes: 4 additions & 0 deletions CS/GridCustomShortcuts/Components/Pages/Index.razor.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ export function removeCaptureKeyListener() {
window.removeEventListener('keydown', keydownHandler, true);
keydownHandler = null;
}
}

export function focusGrid() {
document.getElementsByClassName('dxbl-grid')[0].focus();
}
35 changes: 0 additions & 35 deletions CS/GridCustomShortcuts/Components/Pages/Weather.razor

This file was deleted.

58 changes: 42 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,60 @@
<!-- default badges list -->
![](https://img.shields.io/endpoint?url=https://codecentral.devexpress.com/api/v1/VersionRange/970685143/24.2.1%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/T1290517)
[![](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)
<!-- default badges end -->
# Product/Platform - Task
# Blazor Grid - Custom Keyboard Shortcuts

This is the repository template for creating new examples. Describe the solved task here.
The DevExpress Blazor [Grid](https://docs.devexpress.com/Blazor/403143/components/grid) supports a number of keyboard shortcuts out-of-the-box. You can also define custom key combinations to further enhance interaction speed and streamline workflows according to business requirements or user preferences.

Put a screenshot that illustrates the result here.
This example binds custom keyboard shortcuts to the Grid component:

Then, add implementation details (steps, code snippets, and other technical information in a free form), or add a link to an existing document with implementation details.
- <kbd>Ctrl</kbd> + <kbd>A</kbd>: select all rows
- <kbd>Shift</kbd> + <kbd>Enter</kbd>: open row details

![Blazor Grid Custom Keyboard Shortcuts](images/grid-keyboard-shortcuts.gif)

> [!NOTE]
> For keyboard shortcuts to operate, the Grid component must be focused. To bring the grid into focus, click anywhere within its area.

## Implementation Details

Add [DxGrid](https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxGrid) and [DxPopup](https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxPopup) components to the [page](CS/GridCustomShortcuts/Components/Pages/Index.razor). The popup will display the selected cell's details when a user presses <kbd>Shift</kbd> + <kbd>Enter</kbd>.

Create a [JavaScript file](CS/GridCustomShortcuts/Components/Pages/Index.razor.js) in the project. This file implements the following functions for managing keyboard shortcuts:

- `addCaptureKeyListener` - Attaches a keyboard event listener to the grid and defines custom shortcuts. To prevent default web browser actions for the same key combinations, call `event.stopPropagation();` within the event handler.
- `removeCaptureKeyListener` - Removes the previously attached keyboard event listener.
- `focusGrid` - Focus the grid programmatically on page load. This ensures shortcuts are instantly available.

### Bind JavaScript with .NET Code

In the `@code` section of the [Index.razor](CS/GridCustomShortcuts/Components/Pages/Index.razor) page:

1. Register the JavaScript code in `OnAfterRenderAsync` lifecycle method.
2. Call the `focusGrid` JavaScript function.
3. Call the `addCaptureKeyListener` JavaScript function. Pass the `DotNetObjectReference` (for interoperability from JavaScript to .NET) and a reference to the `<div>` element that surrounds the grid (for capturing keyboard events.)
4. Implement `SelectAllRows` and `HandleKeyDown` JSInvokable methods to handle operations triggered by keyboard shortcuts.

For technical details, read [Call .NET methods from JavaScript functions in ASP.NET Core Blazor](https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/call-dotnet-from-javascript) article.

### Release Resources

In the `@code` section of the [Index.razor](CS/GridCustomShortcuts/Components/Pages/Index.razor) page, implement a `DisposeAsync` method. It removes the keyboard event listener, cleans up JavaScript resources, and frees allocated memory.

For technical details, read [Implement a DisposeAsync method](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync) article.

## Files to Review

- link.cs (VB: link.vb)
- link.js
- ...
- [Index.razor](CS/GridCustomShortcuts/Components/Pages/Index.razor)
- [Index.razor.js](CS/GridCustomShortcuts/Components/Pages/Index.razor.js)

## Documentation

- link
- link
- ...

## More Examples
- [Keyboard Support in Blazor Grid](https://docs.devexpress.com/Blazor/404652/components/grid/keyboard-support)
- [DxGrid Class](https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxGrid)
- [DxPopup Class](https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxPopup)

- link
- link
- ...
<!-- feedback -->
## Does this example address your development requirements/objectives?

Expand Down
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"autoGenerateVb": true,
"autoGenerateVb": false,
"runOnWeb": false
}
Binary file added images/grid-keyboard-shortcuts.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.