First, obviously you need to register a mouse button event hander in your control initialization. In this case, I'm using a double-click event:
MyListView.MouseDoubleClick += new MouseButtonEventHandler(MyListView_MouseDoubleClick);
and then implement the event handler like such:void MyListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)What we are doing is walking up the visual tree starting at the element the generated the mouse event. We stop when we find a ListViewItem, which we can then use to get the corresponding data item. If all you want is the index of the item, use IndexFromContainer() instead.
{
DependencyObject dep = (DependencyObject)e.OriginalSource;
while ((dep != null) && !(dep is ListViewItem))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
return;
MyDataItemType item = (MyDataItemType)MyListView.ItemContainerGenerator.ItemFromContainer(dep);
// Do something with the item...
}
I saw how to get row or item, but how can I get column information from the mouse click position?
ReplyDeleteTry this and see how it works...
ReplyDeleteSystem.Data.DataRowView value = (System.Data.DataRowView)ListViewEmployeeDetails.SelectedValue;
MessageBox.Show(value.Row[0].ToString());
Thanks man its works for me..........:)
DeleteThanks much, you just saved me some time figuring it out. Here is a VB version.
ReplyDeleteDim clickedToDoItem As ToDoItemInfo
Dim dep As DependencyObject = CType(e.OriginalSource, DependencyObject)
Do While dep IsNot Nothing AndAlso Not TypeOf (dep) Is ListViewItem
dep = VisualTreeHelper.GetParent(dep)
Loop
If dep Is Nothing Then
Return
Else
clickedToDoItem = CType(Me.lvToDo.ItemContainerGenerator.ItemFromContainer(dep), ToDoItemInfo)
End If
MessageBox.Show(String.Format("You clicked item: date={0},description={1}", clickedToDoItem.Due, clickedToDoItem.Description))
Thanks for the info. It worked great in my project and helped me solve two issues I was having. I really am starting to like WPF, but it is still taking a long time to figure it all out.
ReplyDeleteThis code fails if the OriginalSource is derived from FrameworkContentElemnt (e.g. anything in a FlowDocument, such as Document.Run). Unfortunately, VisualTreeHelper deals with Visual and FrameworkElement objects, but not FrameworkContentElement objects. 8-|
ReplyDeleteAs the last comment indicated, you need to handle ContentElement's differently. If you hit a content element then you should get the logical parent.
ReplyDeleteThanks a lot for this. Was searching around for ages and found yours to be the most concise method. Thanks
ReplyDeletehi
ReplyDeletegreat code tnx!
Using
ReplyDeleteMyDataItemType item = (MyDataItemType)((ListViewItem)dep).DataContext
instead of
MyDataItemType item = (MyDataItemType)MyListView.ItemContainerGenerator.ItemFromContainer(dep);
is a bit more straight forward but may only work, if data source binding is used for the list view.
That's overly complex.
ReplyDeleteWhy would you do that?
If you have a listview, just do
<ListView SelectedItem="TheSelectedItem" ... >
and in the setter for TheSelectedItem do what you want with it.
I'm assuming you mean to use a binding to TheSelectedItem, but anyway that wouldn't work in my particular case for at least two reasons:
ReplyDelete1. I'm using a multi-selected ListView (SelectionMode of Multiple), so SelectedItem is meaningless.
2. I only want to act in response to mouse double-clicks, not selection.
Responding to a selection is easy, but it isn't what I'm trying to do. In any case, if you want take action on a selection change, a better way to do that is to use the SelectionChanged event.
You can use this as well:
ReplyDeletehttp://social.msdn.microsoft.com/Forums/en-US/wpf/thread/681dea50-6bd2-4676-8161-14416386778d
Or..
ReplyDeleteprivate void appList_MouseDoubleClick(object sender, RoutedEventArgs e) {
ListViewItem app = (ListViewItem)appList.Items[appList.SelectedIndex];
MessageBox.Show("you selected: " + app.Content);
}
Great post!
ReplyDeleteVery Good post!
ReplyDeleteI'm not sure if it would work in your case, Mike, but this worked for me:
ReplyDeleteprivate void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ListViewItem listViewItemSender = sender as ListViewItem;
MyBusinessObject doubleClickedBO = myListView.ItemContainerGenerator.ItemFromContainer(listViewItemSender) as MyBusinessObject;
}
TY - helped my project
ReplyDeleteNice dude! That worked perfectly. :)
ReplyDeleteI am trying to learn WPF and I had been struggling with this for days!
Thanks!
No one is having a problem with the error "expression of type 'System.Windows.DependencyObject' can never be of type 'System.Windows.Forms.ListViewItem'"??? I'm not sure what I'm doing wrong here...
ReplyDeleteThank you for this post!
ReplyDeleteThis is really useful. Thanks for the tip about getting the index number from IndexFromContainer().
ReplyDelete