Skip to content

Commit 1097803

Browse files
kb(grid): which cell was clicked for context menu
1 parent 25664b8 commit 1097803

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
---
2+
title: How do I tell which cell I right clicked in for a context menu?
3+
description: How to tell which grid cell was clicked for context menu
4+
type: how-to
5+
page_title: How to know which grid cell was clicked for context menu
6+
slug: grid-kb-which-cell-context-menu
7+
position:
8+
tags:
9+
ticketid: 1499425
10+
res_type: kb
11+
---
12+
13+
## Environment
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>Grid for Blazor</td>
19+
</tr>
20+
</tbody>
21+
</table>
22+
23+
24+
## Description
25+
When I right click a cell in a Grid, I want to show context menu. I need to know row, column and ideally cell value. When using the [grid context menu event]({%slug grid-events%}#onrowcontextmenu), I need to figure out which column was clicked.
26+
27+
## Solution
28+
To distinguish a column (cell) from the rest, you need to:
29+
30+
1. Use the [cell template]({%slug grid-templates-column%}) for columns that need special handling.
31+
2. [Integrate the context menu there]({%slug contextmenu-integration%}) explicitly.
32+
3. Make sure to stop the event propagation so that the built-in grid event does not trigger.
33+
4. In the specific event handlers for the context menu event, employ your application logic to use the row, and metadata from the event handlers to built the desired context menu experience.
34+
35+
>caption How to tell when the context menu on the grid row was triggered by a specific cell
36+
37+
````CSHTML
38+
This example uses a simple boolean flag for brevity, you can extend the logic to also pass the column name/field or any other metadata you need to use.
39+
40+
<TelerikContextMenu Data="@MenuItems" @ref="@TheContextMenu"
41+
TextField="Text" IconField="Icon" DisabledField="Disabled"
42+
OnClick="@( (ContextMenuItem itm) => ClickHandler(itm) )">
43+
</TelerikContextMenu>
44+
45+
<TelerikGrid Data="@MyData" Height="500px" OnRowContextMenu="@OnContextMenu">
46+
<GridColumns>
47+
<GridColumn Field="@(nameof(SampleData.ID))" Title="Photo">
48+
<Template>
49+
@{
50+
var employee = context as SampleData;
51+
<div @oncontextmenu:preventDefault="true"
52+
@oncontextmenu:stopPropagation="true"
53+
@oncontextmenu="@( (MouseEventArgs e) => ShowSpecialContextMenu(e, employee, true) )">
54+
@* The custom context menu handler here distinguishes one column from another
55+
through the third argument it passes, and the row model distinguishes the row.
56+
we stop the propagation to prevent the built-in handler from the grid that we use for the other columns
57+
*@
58+
@employee.ID
59+
</div>
60+
}
61+
</Template>
62+
</GridColumn>
63+
<GridColumn Field="@(nameof(SampleData.Name))" Title="Employee Name" />
64+
<GridColumn Field="@(nameof(SampleData.HireDate))" Title="Hire Date " />
65+
</GridColumns>
66+
</TelerikGrid>
67+
68+
@code {
69+
public List<ContextMenuItem> MenuItems { get; set; }
70+
TelerikContextMenu<ContextMenuItem> TheContextMenu { get; set; }
71+
SampleData LastClickedItem { get; set; }
72+
73+
// create the special menu for a special column
74+
async Task ShowSpecialContextMenu(MouseEventArgs e, SampleData clickedItem, bool isSpecial)
75+
{
76+
await InitializeMenu(clickedItem, isSpecial, e.ClientX, e.ClientY);
77+
}
78+
79+
// handle the built-in grid event for the standard columns
80+
async Task OnContextMenu(GridRowClickEventArgs args)
81+
{
82+
if (args.EventArgs is MouseEventArgs e)
83+
{
84+
await InitializeMenu(args.Item as SampleData, false, e.ClientX, e.ClientY);
85+
}
86+
}
87+
88+
// menu preparation - here we just enable a menu item for the special column, you can do more
89+
async Task InitializeMenu(SampleData clickedItem, bool isSpecial, double x, double y)
90+
{
91+
LastClickedItem = clickedItem;
92+
// change the menu items
93+
// disable one item, you can make bigger changes here too
94+
MenuItems[0].Disabled = !isSpecial;
95+
// show the menu
96+
await TheContextMenu.ShowAsync(x, y);
97+
}
98+
99+
// sample handling of the context menu action
100+
async Task ClickHandler(ContextMenuItem clickedItem)
101+
{
102+
// handle the command from the context menu by using the stored metadata
103+
if (!string.IsNullOrEmpty(clickedItem.CommandName) && LastClickedItem != null)
104+
{
105+
Console.WriteLine($"The programm will now perform the {clickedItem.CommandName} operation for {LastClickedItem.Name}");
106+
}
107+
LastClickedItem = null;
108+
}
109+
110+
// generate sample data for the menu
111+
protected override void OnInitialized()
112+
{
113+
MenuItems = new List<ContextMenuItem>()
114+
{
115+
new ContextMenuItem
116+
{
117+
Text = "More Info",
118+
Icon = "information",
119+
CommandName = "info"
120+
},
121+
new ContextMenuItem
122+
{
123+
Text = "Delete",
124+
Icon = "delete",
125+
CommandName = "delete"
126+
},
127+
new ContextMenuItem
128+
{
129+
Text = "Report",
130+
Icon = "cancel",
131+
CommandName = "report"
132+
}
133+
};
134+
135+
base.OnInitialized();
136+
}
137+
138+
public class ContextMenuItem
139+
{
140+
public string Text { get; set; }
141+
public string CommandName { get; set; }
142+
public string Icon { get; set; }
143+
public bool Disabled { get; set; }
144+
public List<ContextMenuItem> Items { get; set; }
145+
}
146+
147+
public class SampleData
148+
{
149+
public int ID { get; set; }
150+
public string Name { get; set; }
151+
public DateTime HireDate { get; set; }
152+
}
153+
154+
public IEnumerable<SampleData> MyData = Enumerable.Range(1, 50).Select(x => new SampleData
155+
{
156+
ID = x,
157+
Name = "name " + x,
158+
HireDate = DateTime.Now.AddDays(-x)
159+
});
160+
}
161+
````
162+

0 commit comments

Comments
 (0)