在ListBox中记录用户可见的项目

时间:2011-05-27 05:42:39

标签: wpf datagrid listbox

我有一个ListBox或DataGrid,里面有数以千计的条目。我想知道用户查看的项目(滚动,搜索或其他)。如何判断ListBox中用户可见的内容?

奖励:设置一个计时器,使项目必须显示至少N毫秒(如果用户只是拉下滚动条)。

更新:这是Get items in view within a listbox的近似副本 - 但是使用“SelectedItems”提供的解决方案是不够的。我需要知道它们是否被选中的项目!

1 个答案:

答案 0 :(得分:2)

您需要做的就是获取ListBox中的底层StackPanel。它有足够的信息显示哪些元素正在显示。 (它实现了接口IScrollInfo)。

要从给定的ListBox获取底层StackPanel(或实际上是VirtualizingStackPanel),我们必须使用VisualTreeHelper来浏览Visual Tree并查找VirtualizingStackPanel,如下所示:

    private VirtualizingStackPanel GetInnerStackPanel(FrameworkElement element)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
        {
            var child = VisualTreeHelper.GetChild(element, i) as FrameworkElement;

            if (child == null) continue;

            Debug.WriteLine(child.ToString());

            if (child is VirtualizingStackPanel) return child as VirtualizingStackPanel;

            var panel = GetInnerStackPanel(child);

            if (panel != null)
                return panel;
        }

        return null;

    }

现在我们有StackPanel,我们非常接近。 StackPanel具有属性VerticalOffsetViewportHeight(均来自IScrollInfo),可以为我们提供所需的所有信息。

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        var theStackPanel = GetInnerStackPanel(MyListBox);

        List<FrameworkElement> visibleElements = new List<FrameworkElement>();

        for (int i = 0; i < theStackPanel.Children.Count; i++)
        {

            if (i >= theStackPanel.VerticalOffset && i <= theStackPanel.VerticalOffset + theStackPanel.ViewportHeight)
            {
                visibleElements.Add(theStackPanel.Children[i] as FrameworkElement);
            }
        }


        MessageBox.Show(visibleElements.Count.ToString());
        MessageBox.Show(theStackPanel.VerticalOffset.ToString());
        MessageBox.Show((theStackPanel.VerticalOffset + theStackPanel.ViewportHeight).ToString());

    }
相关问题