【问题标题】:Record items visible to user in ListBox在 ListBox 中记录用户可见的项目
【发布时间】:2011-09-03 03:30:31
【问题描述】:

我有一个 ListBox 或 DataGrid 填充了数千个条目。我想知道用户查看过的项目(滚动、搜索或其他方式)。如何判断 ListBox 中用户可见的内容?

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

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

【问题讨论】:

  • 这可能是另一个线索:stackoverflow.com/questions/610343/…
  • 澄清我想知道:它是什么? ListBox 还是 DataGrid?或者您是否要根据解决方案是否可行而选择两者中的一个而不是另一个?如果您使用的是ListBox,您是否要更改其ItemsPanel 属性?
  • 我正在使用 Xceed 数据网格,但我愿意使用普通数据网格或列表框来完成此操作。
  • 既然您为此开始了赏金并将 Elad 的答案标记为已接受,您可能应该奖励他赏金。按照目前的情况,当赏金窗口结束时,它不会自动发生。

标签: wpf datagrid listbox


【解决方案1】:

您需要做的就是获取 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());

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-24
    • 2019-07-29
    • 1970-01-01
    • 2021-03-23
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多