The key is setting the PreviewMouseRightButtonDown event in the correct place. As you'll notice, even without a ContextMenu right clicking on a ListViewItem will select that item, and so we need to set the event on each item, not on the ListView.
<ListView>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="PreviewMouseRightButtonDown"
Handler="OnListViewItemPreviewMouseRightButtonDown" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Menu Item">Item 1</MenuItem>
<MenuItem Header="Menu Item">Item 2</MenuItem>
</ContextMenu>
</ListView.ContextMenu>
<ListViewItem>Item</ListViewItem>
<ListViewItem>Item</ListViewItem>
<ListViewItem>Item</ListViewItem>
<ListViewItem>Item</ListViewItem>
<ListViewItem>Item</ListViewItem>
<ListViewItem>Item</ListViewItem>
</ListView>
private void OnListViewItemPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
Trace.WriteLine("Preview MouseRightButtonDown");
e.Handled = true;
}
Since the preview events are tunneling this will block the RightMouseButtonDown from occurring on the ListViewItems preventing them from being selected, but not prevent the RightMouseButtonDown on the ListView and so still allow the ContextMenu to open.