Gam*_*ist 14 .net c# vb.net wpf listview
我有一个ListView可能包含很多物品,所以它是virtualized和回收物品.它不使用排序.我需要刷新一些值显示,但是当项目太多时,更新所有内容的速度太慢,所以我只想刷新可见项目.
我怎样才能获得所有当前显示的项目列表?我试图调查ListView或者在里面ScrollViewer,但我仍然不知道如何实现这一目标.如果可以看到解决方案,解决方案不得通过所有项目进行测试,因为这样做太慢了.
我不确定代码或xaml是否有用,它只是一个Virtualized/ Recycling ListView它ItemSource与一个绑定Array.
编辑:
答案:
感谢akjoshi,我找到了方法:
得到ScrollViewer的ListView
(有FindDescendant方法,你可以做你自己用VisualTreeHelper).
读取它ScrollViewer.VerticalOffset:它是显示的第一个项目的编号
ScrollViewer.ViewportHeight:它是显示的项目数.CanContentScroll必须是真的.在MSDN上查看这个问题,展示一种找出可见ListView项目的技术 -
如何在ListView中找到实际可见的行(ListViewItem(s))?
这是该帖子的相关代码 -
listView.ItemsSource = from i in Enumerable.Range(0, 100) select "Item" + i.ToString();
listView.Loaded += (sender, e) =>
{
ScrollViewer scrollViewer = listView.GetVisualChild<ScrollViewer>(); //Extension method
if (scrollViewer != null)
{
ScrollBar scrollBar = scrollViewer.Template.FindName("PART_VerticalScrollBar", scrollViewer) as ScrollBar;
if (scrollBar != null)
{
scrollBar.ValueChanged += delegate
{
//VerticalOffset and ViweportHeight is actually what you want if UI virtualization is turned on.
Console.WriteLine("Visible Item Start Index:{0}", scrollViewer.VerticalOffset);
Console.WriteLine("Visible Item Count:{0}", scrollViewer.ViewportHeight);
};
}
}
};
Run Code Online (Sandbox Code Playgroud)
你应该做的另一件事是用ObservableCollection你的ItemSource而不是Array; 这肯定会提高性能.
更新:
雅可能是真的(array对比ObservableCollection),但我希望看到一些与此相关的统计数据;
真正的好处ObservableCollection是,如果您需要ListView在运行时添加/删除项目,如果您必须Array重新分配其中ItemSource的ListView第ListView一个并丢弃其先前的项目并重新生成其整个列表.
在尝试找出类似的东西后,我想我会在这里分享我的结果(因为它似乎比其他响应更容易):
我从这里得到的简单可见性测试.
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);
}
Run Code Online (Sandbox Code Playgroud)
之后,您可以遍历listboxitems并使用该测试来确定哪些是可见的.由于listboxitems始终排序相同,因此该列表中的第一个可见的列表框将是用户的第一个可见的.
private List<object> GetVisibleItemsFromListbox(ListBox listBox, FrameworkElement parentToTestVisibility)
{
var items = new List<object>();
foreach (var item in PhotosListBox.Items)
{
if (IsUserVisible((ListBoxItem)listBox.ItemContainerGenerator.ContainerFromItem(item), parentToTestVisibility))
{
items.Add(item);
}
else if (items.Any())
{
break;
}
}
return items;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25627 次 |
| 最近记录: |