获取ListView的可见项我有一个ListView,可能包含很多项,所以是虚拟化回收项。它不使用排序。我需要刷新一些值显示,但是当项目太多时,更新一切都太慢了,所以我只想刷新可见的项目。如何获得所有当前显示项目的列表?我试图研究ListView或ScrollViewer,但我仍然不知道如何实现这一点。如果可以看到解决方案,则该解决方案一定不能通过所有项目测试,因为这样做太慢了。我不确定代码或xaml是否有用,它只是一个带有绑定到数组的ItemSource的虚拟化/回收ListView。编辑:回答:多亏了akjoshi,我找到了方法:在MSDN上查看这个问题,展示了一种技术来找出哪些ListView项是可见的——如何在ListView中找到实际可见的行(ListViewItem(s))?这是该帖子中的相关代码–listView.ItemsSource=fromiinEnumerable.Range(0,100)select"Item"+i.ToString();listView.Loaded+=(sender,e)=>{ScrollViewerscrollViewer=listView.GetVisualChild();//扩展方法if(scrollViewer!=null){ScrollBarscrollBar=scrollViewer.Template.FindName("PART_VerticalScrollBar",scrollViewer)asScrollBar;if(scrollBar!=null){scrollBar.ValueChanged+=delegate{//如果开启UI虚拟化,VerticalOffset和ViweportHeight其实就是你想要的。Console.WriteLine("可见项起始索引:{0}",scrollViewer.VerticalOffset);Console.WriteLine("可见项数:{0}",scrollViewer.ViewportHeight);};}}};您应该做的另一件事是使用ObservableCollection作为ItemSource而不是Array;这肯定会提高性能。更新:Ya可能是真的(数组与ObservableCollection)但我想看看与此相关的一些统计数据;ObservableCollection的真正好处是,如果您需要在运行时从ListView添加/删除项目,那么在Array情况下,您将不得不重新分配ListView的ItemSource,并且ListView首先丢弃其先前的项目并重新生成它的整个列表。在尝试找出类似的东西之后,我想我应该在这里分享我的结果(因为它似乎比其他响应更容易):我从这里获得的简单可见性测试。privatestaticboolIsUserVisible(FrameworkElementelement,FrameworkElementcontainer){if(!element.IsVisible)returnfalse;矩形边界=element.TransformToAncestor(container).TransformBounds(newRect(0.0,0.0,element.ActualWidth,element.ActualHeight));varrect=newRect(0.0,0.0,container.ActualWidth,container.ActualHeight);返回rect.Contains(bounds.TopLeft)||rect.Contains(bounds.BottomRight);之后,您可以遍历listboxitems并使用Test来确定哪些是可见的。由于listboxitems总是排序相同,因此该列表中第一个可见的将是第一个对用户可见的。私有列表GetVisibleItemsFromListbox(ListBoxlistBox,FrameworkElementparentToTestVisibility){varitems=newList();foreach(PhotosListBox.Items中的varitem){if(IsUserVisible((ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(item)){.Add(item);}elseif(items.Any()){break;}}返回项目;}我的看法:在最后的工作中,在ObservableCollection上使用绑定是一个很好的建议。如果您要从另一个线程修改ObservableCollection,我建议您这样做:http://blog.quantumbitdesigns.com/2008/07/22/wpf-cross-thread-collection-binding-part-1/我花了很多时间为此找到更好的解决方案,在我的例子中,我有一个滚动查看器,里面装满了具有自定义高度的项目设置为可见/不可见,我想到了这个。它与上面的解决方案相同,但只使用了一小部分CPU。我希望它有所帮助。列表视图/滚动面板的第一项是TopVisibleItempublicintTopVisibleItem{get;私有集;私人双CurrentDistance;privatevoidTouchScroller_ScrollChanged(objectsender,ScrollChangedEventArgse){if(myItemionControl.Directir0.Count){if(myItemionControl.Directir0.Count){)Math.Sign(e.VerticalChange);if(direction==MoveDirection.Positive)while(CurrentDistance=e.VerticalOffset&&TopVisibleItem>0){CurrentDistance-=((FrameworkElement)myItemControl.Items[TopVisibleItem]).ActualHeight;TopVisibleItem-=1;}}}publicenumMoveDirection{Negative=-1,Positive=1,}如果你启用了虚拟化ListView,那么你可以像这样获取所有当前可见的项目:GetVirtualizingStackPanel获取VirtualizingStackPanel中的所有ListViewItems代码如下所示。VirtualizingStackPanelvirtualizingStackPanel=FindVisualChild(requiredListView);列表项=GetVisualChildren(virtualizingStackPanel);功能如下图。privatechildItemFindVisualChild(DependencyObjectobj)wherechildItem:DependencyObject{for(inti=0;i(child);if(childOfChild!=null)returnchildOfChild;}}returnnull;}privateListGetVisualChildren(DependencyObjectobj)其中:childIteDependencyObject{ListchildList=newList();for(inti=0;i0)returnchildList;returnnull;}这将返回当前加载显示的ListViewItem的列表。希望这有帮助:)。以上就是C#学习教程:获取ListView可见项共享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
