The following code will help you solve the problem, the steps are in the comments,
private void ListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
// you can check which mouse button, its state, or use the correct event.
// get the element the mouse is currently over
var uie = ListBox.InputHitTest(Mouse.GetPosition(this.ListBox));
if (uie == null)
return;
// navigate to its ListBoxItem container
var listBoxItem = FindParent<ListBoxItem>((FrameworkElement) uie);
// in case the click was not over a listBoxItem
if (listBoxItem == null)
return;
// here is the index
int index = this.ListBox.ItemContainerGenerator.IndexFromContainer(listBoxItem);
MessageBox.Show(index.ToString());
}
public static T FindParent<T>(FrameworkElement child) where T : DependencyObject
{
T parent = null;
var currentParent = VisualTreeHelper.GetParent(child);
while (currentParent != null)
{
// check the current parent
if (currentParent is T)
{
parent = (T)currentParent;
break;
}
// find the next parent
currentParent = VisualTreeHelper.GetParent(currentParent);
}
return parent;
}
Update
What you wanted is the index of the data item you clicked on. once you get the container, you can't get the index until you get hold of the data item associated with it via the DataContext
, and look for its index in the bound collection. the ItemContainerGenerator
already does that for you.
In your code you're assuming that the ListBoxItem
index is the same index of the data item in the bound collection, this is only true if Virtualization
is turned off. If it is on then only the containers for the items in the visible region are instantiated. For example, if you have 1000 data item in your bound collection, and you've scrolled to the 50th data item, now, theoretically, the ListBoxItem
at index 0 is bound to the 50th data item, which proves that your assumption is wrong.
I said earlier theoretically, because there are some hidden containers created at the top and bottom of the scrolling region when Virtualization
is on, in order for keyboard navigation to work properly.