I'm working with a winForms app that has a listView. That listView has multi-select enabled and I have many, many items in the list (in row view).
我正在使用一个带有listView的winForms应用程序。 listView启用了多选,我在列表中有很多项(在行视图中)。
When I select the last row (i.e. item), then shift-click the 5000th row, SelectedIndexChanged fires 5000 times. If this happens, I end up in a very nasty loop. The last row clicked is not guaranteed to be the last item in the "SelectedItems" list. How do I get the actual item clicked?
当我选择最后一行(即项目)时,然后按住Shift键单击第5000行,SelectedIndexChanged将触发5000次。如果发生这种情况,我最终会陷入一个非常讨厌的循环。单击的最后一行不保证是“SelectedItems”列表中的最后一项。如何点击实际项目?
EDIT: Better clarification: How do I get my hands on the ListViewItem that CAUSED this particular iteration of the SelectedIndexChanged event? ... even if I have to check all 5000 of them. I need to know which one I'm looking at. EventArgs does not have an index property, and sender is the ListView, not the ListViewItem.
编辑:更好的澄清:我如何得到ListViewItem,导致SelectedIndexChanged事件的这个特定迭代? ......即使我必须检查所有5000个。我需要知道我在看哪一个。 EventArgs没有索引属性,sender是ListView,而不是ListViewItem。
Any thoughts?
3 个解决方案
#1
OH, FOR THE LOVE OF PETE... (* feels dumber than a rock *)
哦,为爱的宠爱......(*感觉笨拙而不是摇滚*)
I found my answer. Note that I am using SelectedIndexChanged. There is another event that I should have been using: ItemSelectionChange.
我找到了答案。请注意,我使用的是SelectedIndexChanged。还有一个我应该使用的事件:ItemSelectionChange。
When using that event, I now have events that can tell me which items changed in the selection and it tells me if the item was Selected or Unselected. It's beautiful.
当使用该事件时,我现在有一些事件可以告诉我在选择中哪些项目发生了变化,它告诉我该项目是选中还是未选中。很美丽。
I hope that helps others that are fighting this issue.
我希望能帮助其他人解决这个问题。
#2
Here's the best solution I can think of. Handle the ListView's OnMouseMove event. Whenever the mouse moves, record the location of the mouse. Then when you get a SelectedIndexChangedEvent you can call ListView.FindNearestItem(SearchDirectionHint, Point) and pass in the last mouse coordinates as the Point parameter. This should give you the item that was actually clicked.
这是我能想到的最佳解决方案。处理ListView的OnMouseMove事件。只要鼠标移动,记录鼠标的位置。然后,当您获得SelectedIndexChangedEvent时,可以调用ListView.FindNearestItem(SearchDirectionHint,Point)并将最后一个鼠标坐标作为Point参数传递。这应该为您提供实际点击的项目。
Note you can't depend on it actually returning an item though. It's perfectly possible to select an item without every using the mouse. A couple of tabs and space bar will do the trick. But for actual clicks, this should do the trick.
请注意,你不能依赖它实际返回一个项目。完全可以在不使用鼠标的情况下选择项目。几个标签和空格键可以解决这个问题。但对于实际点击,这应该可以解决问题。
#3
There is a method on ListView
called HitTest
. By handling the event MouseClick
you can determine what the last item that was clicked.
ListView上有一个名为HitTest的方法。通过处理事件MouseClick,您可以确定单击的最后一个项目。
If you want to figure out what the last selected item was, don't forget the keyboard. In a list view control, you can hold down Ctrl+(arrow key)
to move the focus rectangle, and then hit Ctrl+Space
to add to the selection. If you want the last selected item, you will have to handle this too.
如果您想弄清楚最后选择的项目是什么,请不要忘记键盘。在列表视图控件中,您可以按住Ctrl +(箭头键)移动焦点矩形,然后按Ctrl + Space添加到选择中。如果你想要最后选择的项目,你也必须处理这个。
#1
OH, FOR THE LOVE OF PETE... (* feels dumber than a rock *)
哦,为爱的宠爱......(*感觉笨拙而不是摇滚*)
I found my answer. Note that I am using SelectedIndexChanged. There is another event that I should have been using: ItemSelectionChange.
我找到了答案。请注意,我使用的是SelectedIndexChanged。还有一个我应该使用的事件:ItemSelectionChange。
When using that event, I now have events that can tell me which items changed in the selection and it tells me if the item was Selected or Unselected. It's beautiful.
当使用该事件时,我现在有一些事件可以告诉我在选择中哪些项目发生了变化,它告诉我该项目是选中还是未选中。很美丽。
I hope that helps others that are fighting this issue.
我希望能帮助其他人解决这个问题。
#2
Here's the best solution I can think of. Handle the ListView's OnMouseMove event. Whenever the mouse moves, record the location of the mouse. Then when you get a SelectedIndexChangedEvent you can call ListView.FindNearestItem(SearchDirectionHint, Point) and pass in the last mouse coordinates as the Point parameter. This should give you the item that was actually clicked.
这是我能想到的最佳解决方案。处理ListView的OnMouseMove事件。只要鼠标移动,记录鼠标的位置。然后,当您获得SelectedIndexChangedEvent时,可以调用ListView.FindNearestItem(SearchDirectionHint,Point)并将最后一个鼠标坐标作为Point参数传递。这应该为您提供实际点击的项目。
Note you can't depend on it actually returning an item though. It's perfectly possible to select an item without every using the mouse. A couple of tabs and space bar will do the trick. But for actual clicks, this should do the trick.
请注意,你不能依赖它实际返回一个项目。完全可以在不使用鼠标的情况下选择项目。几个标签和空格键可以解决这个问题。但对于实际点击,这应该可以解决问题。
#3
There is a method on ListView
called HitTest
. By handling the event MouseClick
you can determine what the last item that was clicked.
ListView上有一个名为HitTest的方法。通过处理事件MouseClick,您可以确定单击的最后一个项目。
If you want to figure out what the last selected item was, don't forget the keyboard. In a list view control, you can hold down Ctrl+(arrow key)
to move the focus rectangle, and then hit Ctrl+Space
to add to the selection. If you want the last selected item, you will have to handle this too.
如果您想弄清楚最后选择的项目是什么,请不要忘记键盘。在列表视图控件中,您可以按住Ctrl +(箭头键)移动焦点矩形,然后按Ctrl + Space添加到选择中。如果你想要最后选择的项目,你也必须处理这个。