开发者

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 property public 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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜