diff --git a/CS/GridCustomShortcuts/Components/Layout/NavMenu.razor b/CS/GridCustomShortcuts/Components/Layout/NavMenu.razor
index d8ed94b..9e7f610 100644
--- a/CS/GridCustomShortcuts/Components/Layout/NavMenu.razor
+++ b/CS/GridCustomShortcuts/Components/Layout/NavMenu.razor
@@ -2,8 +2,6 @@
-
-
\ No newline at end of file
diff --git a/CS/GridCustomShortcuts/Components/Pages/Counter.razor b/CS/GridCustomShortcuts/Components/Pages/Counter.razor
deleted file mode 100644
index 99a48d8..0000000
--- a/CS/GridCustomShortcuts/Components/Pages/Counter.razor
+++ /dev/null
@@ -1,27 +0,0 @@
-@page "/counter"
-@rendermode InteractiveServer
-Counter
-
-
Counter
-
-
-
-
- @currentCount
-
-
- current count
-
-
-
-
Click me
-
-
-@code {
- private int currentCount = 0;
-
- private void IncrementCount()
- {
- currentCount++;
- }
-}
diff --git a/CS/GridCustomShortcuts/Components/Pages/Counter.razor.css b/CS/GridCustomShortcuts/Components/Pages/Counter.razor.css
deleted file mode 100644
index 08d0ae2..0000000
--- a/CS/GridCustomShortcuts/Components/Pages/Counter.razor.css
+++ /dev/null
@@ -1,37 +0,0 @@
-.counter-block {
- display: flex;
- padding: 2.5rem 1.5rem 1.5rem 1.5rem;
- flex-direction: column;
- border-radius: 1rem;
- gap: 1.5rem;
- justify-content: center;
- align-items: center;
- width: 16.875rem;
- height: 17rem;
- position: relative;
-}
-
- .counter-block .counter-content {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 0.5rem;
- }
-
- .counter-block .counter-count {
- font-size: 7.5rem;
- font-weight: 400;
- line-height: 7.75rem;
- }
-
- .counter-block .counter-block-back {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: var(--bs-body-color);
- opacity: 0.05;
- border-radius: 1rem;
- z-index: -2;
- }
diff --git a/CS/GridCustomShortcuts/Components/Pages/Index.razor b/CS/GridCustomShortcuts/Components/Pages/Index.razor
index e4b156b..2a6134d 100644
--- a/CS/GridCustomShortcuts/Components/Pages/Index.razor
+++ b/CS/GridCustomShortcuts/Components/Pages/Index.razor
@@ -6,6 +6,9 @@
@inject WeatherForecastService ForecastService
@implements IAsyncDisposable
+Blazor Grid Keyboard Shortcuts
+Weather Forecast
+
@if (forecasts == null)
{
Loading...
@@ -13,13 +16,12 @@
else
{
-
+
-
+
@@ -28,10 +30,10 @@ else
-
-
+
+ Temperature: @selectedForecast?.TemperatureC °C
+ Summary: @selectedForecast?.Summary
}
@@ -39,7 +41,7 @@ else
private WeatherForecast[]? forecasts;
private bool popupVisible;
private ElementReference gridWrapper;
- private DateOnly currentDate;
+ private WeatherForecast? selectedForecast;
private IGrid grid;
private IJSObjectReference? module;
private DotNetObjectReference? dotNetHelper;
@@ -51,7 +53,7 @@ else
if (focusedItem == null)
return;
await grid.SaveChangesAsync();
- currentDate = focusedItem.Date;
+ selectedForecast = focusedItem;
popupVisible = true;
StateHasChanged();
}
@@ -74,6 +76,7 @@ else
module = await JS.InvokeAsync("import",
"./Components/Pages/Index.razor.js");
dotNetHelper = DotNetObjectReference.Create(this);
+ await module.InvokeVoidAsync("focusGrid");
await module.InvokeVoidAsync("addCaptureKeyListener", gridWrapper, dotNetHelper);
}
}
diff --git a/CS/GridCustomShortcuts/Components/Pages/Index.razor.js b/CS/GridCustomShortcuts/Components/Pages/Index.razor.js
index f7296e2..d108705 100644
--- a/CS/GridCustomShortcuts/Components/Pages/Index.razor.js
+++ b/CS/GridCustomShortcuts/Components/Pages/Index.razor.js
@@ -23,4 +23,8 @@ export function removeCaptureKeyListener() {
window.removeEventListener('keydown', keydownHandler, true);
keydownHandler = null;
}
+}
+
+export function focusGrid() {
+ document.getElementsByClassName('dxbl-grid')[0].focus();
}
\ No newline at end of file
diff --git a/CS/GridCustomShortcuts/Components/Pages/Weather.razor b/CS/GridCustomShortcuts/Components/Pages/Weather.razor
deleted file mode 100644
index fb64630..0000000
--- a/CS/GridCustomShortcuts/Components/Pages/Weather.razor
+++ /dev/null
@@ -1,35 +0,0 @@
-@page "/weather"
-
-@using GridCustomShortcuts.Services
-@attribute [StreamRendering(true)]
-@rendermode InteractiveServer
-@inject WeatherForecastService ForecastService
-
-Weather
-Weather
-
-@if (forecasts == null)
-{
- Loading...
-}
-else
-{
-
-
-
-
-
-
-
-
-}
-
-@code {
- private WeatherForecast[]? forecasts;
-
- protected override async Task OnInitializedAsync()
- {
- forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
- }
-}
\ No newline at end of file
diff --git a/README.md b/README.md
index f258469..d8a3300 100644
--- a/README.md
+++ b/README.md
@@ -1,34 +1,60 @@
-
[](https://supportcenter.devexpress.com/ticket/details/T1290517)
[](https://docs.devexpress.com/GeneralInformation/403183)
[](#does-this-example-address-your-development-requirementsobjectives)
-# 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.
+- Ctrl + A: select all rows
+- Shift + Enter: open row details
+
+
+
+> [!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 Shift + Enter.
+
+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 `` 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
-- ...
## Does this example address your development requirements/objectives?
diff --git a/config.json b/config.json
index d660d4a..038dbef 100644
--- a/config.json
+++ b/config.json
@@ -1,4 +1,4 @@
{
- "autoGenerateVb": true,
+ "autoGenerateVb": false,
"runOnWeb": false
}
\ No newline at end of file
diff --git a/images/grid-keyboard-shortcuts.gif b/images/grid-keyboard-shortcuts.gif
new file mode 100644
index 0000000..8b4395f
Binary files /dev/null and b/images/grid-keyboard-shortcuts.gif differ