UWP技术问询:右键DataGrid行能否弹出MenuFlyout?已实现单元格右键菜单
Absolutely! You can absolutely implement a right-click menu that triggers when you click anywhere on a DataGrid row. Your current code adds the menu to a Grid inside a cell, which is why it only works for that specific cell. Here's how to adjust it for row-level context menus:
Step 1: Move the ContextFlyout to DataGridRow
Instead of embedding the MenuFlyout in your cell template, define it in the RowStyle of your DataGrid. This attaches the menu to the entire row, so right-clicking any part of the row will trigger it.
Here's the updated XAML:
<controls:DataGrid x:Name="DataGrid" ItemsSource="{Binding YourDataSource}"> <!-- Keep your existing column definitions (adjust as needed) --> <controls:DataGridTemplateColumn Header="OrderId"> <controls:DataGridTemplateColumn.CellTemplate> <DataTemplate> <!-- No need for the Grid with ContextFlyout here anymore --> <TextBlock Text="{Binding OrderId}" /> </DataTemplate> </controls:DataGridTemplateColumn.CellTemplate> </controls:DataGridTemplateColumn> <!-- Add your other columns here --> <!-- Define the row-level context menu --> <controls:DataGrid.RowStyle> <Style TargetType="controls:DataGridRow"> <Setter Property="ContextFlyout"> <Setter.Value> <MenuFlyout> <MenuFlyoutItem Text="Copy" Icon="Copy" Click="MenuFlyoutItem_Copy" /> <MenuFlyoutSeparator /> <MenuFlyoutItem Text="Delete" Icon="Delete" Click="MenuFlyoutItem_Delete" /> </MenuFlyout> </Setter.Value> </Setter> </Style> </controls:DataGrid.RowStyle> </controls:DataGrid>
Step 2: Simplify the Event Handler Code
Since the menu is now attached to the row, the DataContext of each MenuFlyoutItem will directly be the SampleOrder object for that row. This lets you simplify your event handlers (and add some null checks for robustness):
private void MenuFlyoutItem_Copy(object sender, RoutedEventArgs e) { // Safely cast the ItemsSource and selected item if (DataGrid.ItemsSource is ObservableCollection<SampleOrder> dataGridCollection && sender is MenuFlyoutItem menuItem && menuItem.DataContext is SampleOrder selectedOrder) { var copiedItem = (SampleOrder)selectedOrder.Clone(); dataGridCollection.Add(copiedItem); } } private void MenuFlyoutItem_Delete(object sender, RoutedEventArgs e) { if (DataGrid.ItemsSource is ObservableCollection<SampleOrder> dataGridCollection && sender is MenuFlyoutItem menuItem && menuItem.DataContext is SampleOrder selectedOrder) { dataGridCollection.Remove(selectedOrder); } }
Key Notes
- This setup ensures the menu appears when right-clicking anywhere on the row (not just a specific cell).
- If you still want to keep cell-specific menus alongside the row menu, you can leave your original cell template code intact—just be aware that the cell's menu will take precedence if you right-click directly on the cell content.
内容的提问来源于stack exchange,提问作者James Ellis

