I have a ListView databinded to a ObservableCollection of a class. I'm trying to add a "Copy" menu item to the ListView like so:
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Command="{x:Static ApplicationCommands.Copy}"></MenuItem>
<MenuItem Command="{x:Static ApplicationCommands.Copy}"
CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"></MenuItem>
</ContextMenu>
</ListView.ContextMenu>
Now when i right click a menu item.. the menu comes up but the Copy is grayed out.. my educated guess is that it thinks there's nothing for it to copy.. but that doesn't make sense because when i right click a listbox item.. i'm technically selecting something for it to copy.. and the listbox item is selected as i'm doing this..I just want it to copy the selected text in the ListView.
What do I have to do to get this to work? Overwrite a copy class in my class that's binded to the Listview? I tried googling and not getting very far.
I've just put together an example that works for me:
<Window.CommandBindings>
<CommandBinding
Command="ApplicationCommands.Copy"
CanExecute="CommandBinding_CanExecute"
Executed="CommandBinding_Executed"/>
</Window.CommandBindings>
<Window.Resources>
<ContextMenu x:Key="MyContextMenu">
<MenuItem Header="Copy" Command="ApplicationCommands.Copy"/>
</ContextMenu>
<Style x:Key="MyItemContainerStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu" Value="{StaticResource MyContextMenu}" />
</Style>
</Window.Resources>
<Grid>
<ListView x:Name="MyListView" ItemContainerStyle="{StaticResource MyItemContainerStyle}"/>
</Grid>
Then in the code behind:
// Test class with a single string property
private class MyData
{
public String Name { get; set; }
public MyData(String name)
{
Name = name;
}
public override string ToString()
{
return Name;
}
}
public MainWindow()
{
InitializeComponent();
// Create some test data
ObservableCollection<MyData> names = new ObservableCollection<MyData>();
names.Add(new MyData("Name 1"));
names.Add(new MyData("Name 2"));
names.Add(new MyData("Name 3"));
MyListView.ItemsSource = names;
}
private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
Clipboard.SetText(MyListView.SelectedItem.ToString());
}
This works whether you select Copy
from the context menu, or use Ctrl+C
Without having you rewrite everything, the thing to note about Gary's sample is the presence of a CanExecute statement, which is what controls the enabling/disabling of commands. You should look in to the proper command structure some more, because I think you're missing the real power of the command.
https://msdn.microsoft.com/en-us/library/ms753200%28v=vs.110%29.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With