【问题标题】:Empty space appears at the top of ListView when removing Groups删除Groups时ListView顶部出现空白
【发布时间】:2023-03-30 14:34:02
【问题描述】:

我的音乐播放器在 Details 模式下使用 ListView 显示曲目,并使用 ListViewGroup 将专辑曲目分组。

当专辑的 ListViewGroup 被中键单击时,我创建了删除一张专辑中所有曲目的事件。如果 ListView 在删除曲目时没有向下滚动,则可以正常工作。如果 ListView 向下滚动,相册将被删除,但在 ListView 顶部,标题和第一组之间会出现大的不可点击的空白区域。

ListView 中的第一张图片,3 个相册(向上滚动)


第二张图片,上一张专辑已删除,一切都很好!


好的,那么ListView在移除一组item的时候向下滚动

ListView 中的第三张图片,3 个相册(向下滚动)


第四张图片,最后一张专辑被删除,顶部出现空白区域,如果 ListView 根本没有显示,则最后一首曲目!


我认为这与我的代码无关,而是 ListView 中的错误?有人注意到同样的行为吗?有什么技巧可以防止这种情况发生吗?


编辑:添加删除项目的代码(根据用户要求)

List<ListViewItem> delItems = new List<ListViewItem>(); // creating list of items to be removed

foreach (ListViewGroup group in listView1.Groups)
{
    if (Convert.ToInt32(group.Tag) == groupNumber) // all groups have individual number in tag field
    {
        foreach (ListViewItem item in group.Items)
        {
            delItems.Add(item);
        }
    }
}

foreach (ListViewItem item in delItems)
{
    item.Remove();
}

EDIT2:添加了检查组是否被点击的代码

由于没有真正的方法来处理组点击,我把它弄得很丑。但它有效。 首先,我在 ListView 中使用了 MouseDown 事件。然后我检查是否有用户点击的项目。如果用户单击 group,则 item 为 null,for 循环增加 i 并检查是否现在可以找到 item。当最终找到项目时,我们知道该项目属于我们单击的组。所以我们得到项目组标签,我在其中记录它是什么组。

private void listView1_MouseDown(object sender, MouseEventArgs e)
{
    ListViewItem item;

    for (int i = 0; i < 25; i++) // group height is not more that 25 pixels.
    {
        item = listView1.GetItemAt(e.X, e.Y + i);

        if (item != null)
        {
            if (i > 1) // bigger than 1, because there is 1 pixel gap between listviewitems when using groups
            {
                if (e.Button == MouseButtons.Middle) removePlaylistGroup(Convert.ToInt32(item.Group.Tag));
            }
            else
            {
                if (e.Button == MouseButtons.Middle) removePlaylistItem(item.Index);
            }
            break;
        }
    }
}

【问题讨论】:

  • 在不同的机器上运行时你能重现它吗?我同意您的评估,即可能与您的代码无关,但我以前从未见过这种情况。
  • 是的,它发生在另一个 Win7 和 Win8.1 中。
  • @darx:你能告诉我们删除项目的代码吗?
  • @TaW:代码添加到原始问题。

标签: c# winforms listview listviewgroup


【解决方案1】:

所有这一切都是因为从ListView 中删除项目显然会触发Form1_Layout 事件。在那里,如果表单布局发生变化,我使用listView1.BeginUpdate() ... 来调整listView1 的大小。不知何故,这弄乱了我的 listView。

【讨论】:

  • 我建议使用listView1.SuspendLayout() - listView1.ResumeLayout() 对来构建删除循环。顺便说一句,您如何捕获 Group Click?我知道我可以继承 ListView 并覆盖 WndProc 来捕捉它;但是我不知道如何识别被点击的组..!?
  • 与 Suspend/ResumeLayout() 无关。这里的诊断是缺少对 ListView.EndUpdate() 的调用。但实际上,不要在 Layout 事件处理程序中调用 BeginUpdate()。仅当您对 Items 集合进行批量更改时才应使用它。如果您有闪烁问题,请通过从 ListView 派生您自己的类并在构造函数中将其 DoubleBuffered 属性设置为 true 来修复它们。
  • @TaW:我添加了代码来展示如何确定组点击。如果您不理解我的解释,请随时询问:P
  • @HansPassant:我从布局中删除了 beginupdate。我通过过滤掉 WM_ERASEBKGND 消息来处理闪烁问题,因此当列表视图中发生某些事情时,不会一次又一次地绘制背景。完美运行。双缓冲也已启用。
  • 呃,我希望很快见到你,并抱怨列表视图中的文字看起来很糟糕。
猜你喜欢
  • 2020-01-23
  • 2016-07-09
  • 2017-12-08
  • 2014-06-14
  • 1970-01-01
  • 1970-01-01
  • 2011-05-23
  • 2016-12-28
  • 1970-01-01
相关资源
最近更新 更多