Get items in view within a listbox
I have a ListBox with the property VirtualizingStackPanel.VirtualizationMode set to "Recycling".
I am binding a custom collection (imple开发者_如何学Goments IList
and IList<T>
) to it.
Now, if I understand right, when data is bound, GetEnumerator is called.
And then propertypublic T this[int index] { }
is called for every item in the current view.
My question is how to get the items that are currently visible (after the data is loaded)?
Sometime back i also faced the same issue. I found a workaround of my problem by using "SelectedItem" of Listbox as selected item would be visible always. In my case it was Scrolling which was causing issue. You can have a look if it helps -
Virtualization issue in listbox
Also - Virtualization scrollview - Good One
After trying to figure out something similar, I thought I would share my result here (as it seems easier than the other responses):
Simple visibility test I got from here.
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);
}
Afterwards you can loop through the ListBoxItems and use that test to determine which are visible.
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;
}
精彩评论