I'm trying to display a context menu on individual cells of a DataGrid. When the user right-clicks the cell, I want a context menu showing 'copy to clipboard' to appear, and upon clicking it, it copies the cell text to the clipboard. I have code working for TextBlock of a StackPanel, but not for cell of DataGrid. I've taken grek40's solution from Right click and copy content menu on c# WPF datagrid and got it working, however, its not working for the datagrid cells in the code provided below. In the comments of grek40's solution, michauzo suggests looking at Create contextmenus for datagrid rows and modifying it by "passing the item as a command parameter". However, since I am learning WPF, and I am unsure what the solution is here.
The XAML is as follows:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy"
Executed="CopyCommand_Executed"
CanExecute="CopyCommand_CanExecute"/>
</Window.CommandBindings>
<Window.Resources>
<ContextMenu x:Key="ctMenu" DataContext="{Binding PlacementTarget,RelativeSource={RelativeSource Self}}">
<MenuItem Header="Copy to clipboard"
Command="ApplicationCommands.Copy"
CommandTarget="{Binding}"
CommandParameter="{Binding Text}"/>
</ContextMenu>
</Window.Resources>
<Grid>
<TabControl Name="MainTabControl">
<TabItem Name="StackPanelTab" Header="StackPanel Tab" Margin="24,-2,-28,0">
<StackPanel>
<TextBlock Text="123" ContextMenu="{StaticResource ctMenu}"/>
<TextBlock Text="456" ContextMenu="{StaticResource ctMenu}"/>
</StackPanel>
</TabItem>
<TabItem Name="DataGridTab" Header="DataGrid Tab" Margin="31,-2,-35,0">
<DataGrid Name="datagrid1">
</DataGrid>
</TabItem>
</TabControl>
</Grid>
</Window>
The code behind is as follows:
using System.Windows;
using System.Windows.Input;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<User> users = new List<User>();
users.Add(new User() { Id = 1, Name = "Jane"});
users.Add(new User() { Id = 2, Name = "Bob" });
datagrid1.ItemsSource = users;
}
private void CopyCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
Clipboard.SetText(e.Parameter as string);
}
private void CopyCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Parameter as string))
{
e.CanExecute = true;
e.Handled = true;
}
}
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
}