【问题标题】:How to get the item count in the first row of a WrapPanel?如何获取 WrapPanel 第一行中的项目数?
【发布时间】:2014-01-15 09:49:11
【问题描述】:

将相同高度的 UIElement 列表添加到 WrapPanel,XAML 为

<Grid>
    <ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
    </ListView >
</Grid>

运行时是这样的

为了得到第一行的项目数,我尝试计算每个项目左上角的坐标(相对于列表视图),通过比较每个项目与第一个项目的垂直偏移量,我可以得到第一行的项目数。

但如果项目的高度不同,代码很容易中断。

ListView listView = (sender as ListView);
if (listView.Items.Count > 0)
{
    UIElement firstItem = ((listView.Items)[0] as UIElement);
    double y = firstItem.TranslatePoint(new Point(0, 0), listView).Y; 

    int counter = 0;
    foreach (UIElement item in listView.Items)
    {
        if ((item.TranslatePoint(new Point(0, 0), listView).Y != y))
        {
            break;
        }
        counter++;
    }
}

这样做的正确方法是什么?

【问题讨论】:

  • 帖子中的截图是link,抱歉我在编辑帖子时遇到了问题...
  • 如果项目不是 UIElements,代码当然会失败。你至少应该使用ListView.ItemContainerGenerator.ContainerFromItem
  • 为什么不检查当前项位置的X值是否小于或等于前一项。这将表明发生了换行。
  • @Clemens 是的!这很明显,检查 X 值,太棒了!但我从来没想过,我一直在寻找像 WrapPanel.Row 这样的神奇附加属性,它可以给我答案。
  • @Clemens 您能否将其发布为答案以便我接受?谢谢

标签: wpf wrappanel


【解决方案1】:

这个方法应该可以完成工作:

private static int GetItemsInFirstRow(ItemsControl itemsControl)
{
    double previousX = -1;
    int itemIndex;

    for (itemIndex = 0; itemIndex < itemsControl.Items.Count; itemIndex++)
    {
        var container = (UIElement)itemsControl.ItemContainerGenerator
                                                .ContainerFromIndex(itemIndex);

        var x = container.TranslatePoint(new Point(), itemsControl).X;

        if (x <= previousX)
        {
            break;
        }

        previousX = x;
    }

    return itemIndex;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 2021-12-15
    相关资源
    最近更新 更多