+
ShowAppointmentContextMenu(e, context.Appointment))">
+ @context.Appointment.Subject
+
+
;
+}
+```
+
+**Index.razor.cs**
+```csharp
+private async Task ShowAppointmentContextMenu(MouseEventArgs e, DxSchedulerAppointmentItem appointment) {
+ if(ContextMenu is null || appointment is null)
+ return;
+
+ ClickedRegion = "Appointment";
+ ContextMenuAppointment = appointment;
+ await ContextMenu.ShowAsync(e);
+}
+
+```
+
+#### Other Regions
+
+The example relies on the [appointmentContextMenu.js](CS/wwwroot/js/appointmentContextMenu.js) module to process the following Scheduler regions: date header, time cell, resource header, all-day cell, and day-of-week header. The module handles the browser's `contextmenu` event, determines region by a CSS class, and displays the appropriate menu on the .NET side of the application.
+
+The [OnHtmlCellDecoration](CS/Components/Pages/Index.razor.cs#L160) event handler is used to apply custom CSS classes to Scheduler regions.
+
+**Index.razor.cs**
+```csharp
+private void OnHtmlCellDecoration(SchedulerHtmlCellDecorationEventArgs e) {
+ switch(e.CellType) {
+ case SchedulerCellType.DateHeader:
+ e.CssClass = "custom-date-header";
+ break;
+ case SchedulerCellType.TimeCell:
+ e.CssClass = "custom-time-cell";
+ break;
+ case SchedulerCellType.ResourceHeader:
+ e.CssClass = "custom-resource-header-" + e.Resources.FirstOrDefault()?.Id;
+ break;
+ case SchedulerCellType.AllDayTimeCell:
+ e.CssClass = "custom-all-date-time-cell";
+ break;
+ case SchedulerCellType.DayOfWeekHeader:
+ e.CssClass = "custom-day-of-week-header";
+ break;
+ case SchedulerCellType.None:
+ e.CssClass = "custom-none";
+ break;
+ }
+}
+```
+
+The [getRegion](CS/wwwroot/js/appointmentContextMenu.js) method determines an event target, matches region CSS classes, and passes region name (along with an optional resource `id` and cell `start_date`) back to the Scheduler component:
+
+**appointmentContextMenu.js**
+```js
+export function setup(schedulerElement, dotNetRef) {
+ schedulerElement.addEventListener('contextmenu', (e) => {
+ e.preventDefault();
+ const region = getRegion(e.target, schedulerElement);
+ if (!region) return;
+ dotNetRef.invokeMethodAsync('ShowAppointmentContextMenu',
+ e.clientX, e.clientY, e.pageX, e.pageY, region.name, region.id, region.start_date);
+ });
+}
+```
+
+When a region is detected, the module calls the [[JSInvokable] ShowAppointmentContextMenu](CS/Components/Pages/Index.razor.cs#L83) method which then sets the `ClickedRegion` value and displays the menu at the cursor position.
+
+**Index.razor.cs**
+```csharp
+[JSInvokable]
+public async Task ShowAppointmentContextMenu(double clientX, double clientY, double pageX, double pageY, string region, int? id, long? startDate) {
+ ClickedRegion = region;
+ ClickedId = id;
+ DayToGo = startDate.HasValue ? DateTimeOffset.FromUnixTimeMilliseconds(startDate.Value).DateTime : null;
+
+ StateHasChanged();
+
+ await (ContextMenu?.ShowAsync(new MouseEventArgs {
+ ClientX = clientX,
+ ClientY = clientY,
+ PageX = pageX,
+ PageY = pageY
+ }) ?? Task.FromResult(false));
+}
+```
+
+> [!NOTE]
+> The [appointmentContextMenu.js](CS/wwwroot/js/appointmentContextMenu.js) module relies on DevExpress internal CSS classes (`dxbl-sc-*`, `dxbl-v-*`). These classes may change between release cycles. Review and update them as necessary when/if you upgrade DevExpress-powered Blazor app.
+
+### Region-Aware Menu Commands
+
+[Index.razor](CS/Components/Pages/Index.razor#L83) declares a single [DxContextMenu](https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxContextMenu) used for all regions. Its items are generated dynamically based on the `ClickedRegion` value. A `switch` block renders [DxContextMenuItem](https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxContextMenuItem) items applicable to a clicked region and the current view. For example, "Open this day in Day View" is hidden when the Day View is active.
+
+**Index.razor**
+```razor
+