在WPF ListView C#中获取第一个可见项

任何人都知道如何通过抓取ListView中的第一个可见项来获取ListViewItem? 我知道如何在索引0处获取项目,但不知道第一个可见的项目。

上class很痛苦:

HitTestResult hitTest = VisualTreeHelper.HitTest(SoundListView, new Point(5, 5)); System.Windows.Controls.ListViewItem item = GetListViewItemFromEvent(null, hitTest.VisualHit) as System.Windows.Controls.ListViewItem; 

以及获取列表项的function:

 System.Windows.Controls.ListViewItem GetListViewItemFromEvent(object sender, object originalSource) { DependencyObject depObj = originalSource as DependencyObject; if (depObj != null) { // go up the visual hierarchy until we find the list view item the click came from // the click might have been on the grid or column headers so we need to cater for this DependencyObject current = depObj; while (current != null && current != SoundListView) { System.Windows.Controls.ListViewItem ListViewItem = current as System.Windows.Controls.ListViewItem; if (ListViewItem != null) { return ListViewItem; } current = VisualTreeHelper.GetParent(current); } } return null; } 

在尝试找出类似的东西之后,我想我会在这里分享我的结果(因为它似乎比其他响应更容易):

我从这里得到的简单可见性测试。

 private static bool IsUserVisible(FrameworkElement element, FrameworkElement container) { if (!element.IsVisible) return false; Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight)); var rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight); return rect.Contains(bounds.TopLeft) || rect.Contains(bounds.BottomRight); } 

之后,您可以遍历listboxitems并使用该测试来确定哪些是可见的。 由于listboxitems总是排序相同,因此该列表中的第一个可见的将是用户的第一个可见的。

 private List GetVisibleItemsFromListbox(ListBox listBox, FrameworkElement parentToTestVisibility) { var items = new List(); foreach (var item in PhotosListBox.Items) { if (IsUserVisible((ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(item), parentToTestVisibility)) { items.Add(item); } else if (items.Any()) { break; } } return items; } 

我们只需计算列表框的偏移量,第一个可见项就是索引处的项目等于VerticalOffset …

  // queue is the name of my listbox VirtualizingStackPanel panel = VisualTreeHelper.GetParent(queue.Items[0] as ListBoxItem) as VirtualizingStackPanel; int offset = (int)panel.VerticalOffset; // then our desired listboxitem is: ListBoxItem item = queue.Items[offset] as ListBoxItem; 

希望这对你有所帮助。 。 。!