There are a couple of issues here.
First of all, KeyBindings will only work if the currently focused element is inside the element in which KeyBindings are defined. In your case, you have a ListBoxItem focused, but KeyBindings defined for the child - TextBlock . Thus, defining KeyBindings in a TextBlock will not work anyway, since a TextBlock cannot get focus.
Secondly, you probably need to know what you need to copy, so you need to pass the currently selected log item as a parameter to the Copy command.
In addition, if you define the ContextMenu element in the TextBlock element, it will be open only if you right-click on the TextBlock . If you click on any other part of the list item, it will not open. So, you need to define ContextMenu in the list item itself.
Given all this, I believe that you are trying to do this as follows:
<ListBox ItemsSource="{Binding Logs, Mode=OneWay}" x:Name="logListView" IsSynchronizedWithCurrentItem="True"> <ListBox.InputBindings> <KeyBinding Key="C" Modifiers="Ctrl" Command="Copy" CommandParameter="{Binding Logs/}" /> </ListBox.InputBindings> <ListBox.CommandBindings> <CommandBinding Command="Copy" Executed="CopyLogExecuted" CanExecute="CanExecuteCopyLog" /> </ListBox.CommandBindings> <ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Command="Copy" CommandParameter="{Binding}" /> </ContextMenu> </Setter.Value> </Setter> </Style> </ListBox.ItemContainerStyle> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
Here we define the KeyBinding the ListBox itself and specify the CommandParameter ( CommandParameter entry) as the current item in the list.
CommandBinding also defined at the ListBox level, and this is the only binding for both the context menu and quick access.
ContextMenu we define the ListBoxItem style and bind the CommandParameter to the data item represented by this ListBoxItem ( ListBoxItem entry).
DataTemplate simply declares a TextBlock bound to the current data item.
And finally, there is only one handler for the Copy command in the code:
private void CopyLogExecuted(object sender, ExecutedRoutedEventArgs e) { var logItem = e.Parameter;