【问题标题】:C++ ListView hide itemC++ ListView 隐藏项
【发布时间】:2014-09-04 09:11:28
【问题描述】:

我已经创建了很多标准的 ListView。

    RECT rec;
    GetClientRect(hwnd, &rec);
    ListView = CreateWindow(WC_LISTVIEW, (LPCSTR)L"", (WS_CHILD | WS_VISIBLE | LVS_REPORT), 0, 0, rec.right, rec.bottom-23, hwnd, (HMENU)8553, GetModuleHandle(NULL), NULL);
    SendMessage(ListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES); // Set style

现在我插入几列这样的:

    LVCOLUMNW listColumnW = { 0 };
    listColumnW.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
    listColumnW.pszText = L"Column1";
    listColumnW.cx = 150;
    listColumnW.fmt = LVCFMT_LEFT;
    SendMessage(ListView,LVM_INSERTCOLUMNW, 0, (LPARAM)&listColumnW);

然后我插入项目和子项目

    LVITEMW lisW = { 0 };
    lisW.mask = LVIF_TEXT | LVIF_PARAM;
    lisW.pszText = item_text[i];
    lisW.iItem = i;
    lisW.lParam = i;
    SendMessage(ListView, LVM_INSERTITEMW, 0, (LPARAM)&lisW);

现在我想实现某种搜索/过滤。 我看到很多人建议删除/重新插入项目,但是因为我的列表视图中有相当多的项目不是最佳解决方案。 在谷歌搜索时,我了解到应该可以设置 groupid 和设置项目状态(隐藏它)。 但是我不确定该怎么做,假设我的列表视图中有 10 个项目,我想隐藏一些项目,我该怎么做?

编辑:

我设置了 LVM_ENABLEGROUPVIEW 并创建了两个组,一个应该显示,另一个隐藏。

    LVGROUP group = { 0 };
    group.cbSize = sizeof(LVGROUP);
    group.mask = LVGF_GROUPID;
    group.iGroupId = 10;//shown
    ListView_InsertGroup(ListView, -1, &group);
    group.iGroupId = 11;//hidden
    group.mask = LVGF_GROUPID | LVGF_STATE;
    group.stateMask = LVGS_HIDDEN;
    group.state = LVGS_HIDDEN;
    ListView_InsertGroup(ListView, -1, &group);

现在我已经在两个组中添加了一些项目,唯一的问题是我可以看到它们(它们是分开的),而另一个应该是隐藏的。

【问题讨论】:

  • 尝试将LVGS_NOHEADERLVGS_COLLAPSED 添加到第二组的state。显然简单地设置LVGS_HIDDEN 隐藏组标题而不是组中的项目,但是如果你折叠“隐藏”组,那么它的项目将不会被看到。
  • 谢谢,它成功了。但是更改 groupid 并不比添加项目快,是的,我已经完成了所有优化,例如仅将 id 更改为更改组的项目。对于大约 40 000 个项目,这可能需要一分钟多的时间,所以我确实会尝试虚拟列表。

标签: c++ windows listview winapi


【解决方案1】:

使用LVM_SETITEM 通过LVITEM::iGroupId 成员将列表项分配给特定组:

LVITEMW lisW = { 0 };
lisW.mask = ... | LVIF_GROUPID;
...
lisW.iItem = ...;
lisW.iGroupId = ...;
SendMessage(ListView, 0, (LPARAM)&lisW);

您可以使用LVM_INSERTGROUP 插入隐藏组,或使用LVM_SETGROUPINFO 隐藏现有组,方法是将其LVGROUP::state 成员设置为LVGS_HIDDEN

LVGROUP grp = { 0 };
grp.cbSize = sizeof(grp);
grp.mask = LVGF_STATE;
grp.iGroupId = ...;
grp.stateMask = LVGS_HIDDEN | LVGS_NOHEADER | LVGS_COLLAPSED;
grp.state = LVGS_HIDDEN | LVGS_NOHEADER | LVGS_COLLAPSED;

SendMessage(ListView, LVM_INSERTGROUP, -1, (LPARAM)&grp);
or:
SendMessage(ListView, LVM_SETGROUPINFO, grp.iGroupId, (LPARAM)&grp);

确保您事先已通过LVM_ENABLEGROUPVIEW 启用群组:

SendMessage(ListView, LVM_ENABLEGROUPVIEW, TRUE, 0);

话虽如此,当您在 ListView 中显示/搜索/过滤大量项目时,通常最好使用 virtual mode 中的 ListView。您可以根据需要预先过滤您的数据,然后使用LVM_SETITEMCOUNT 指定要显示的项目数,然后处理LVN_GETDISPINFO 以在ListView 向您请求时检索特定项目的数据。这样,您可以直接在数据源中(在内存中、在数据库中等)进行所有搜索/过滤,然后当您有新数据时,只需使用 LVM_REDRAWITEMS 使需要在屏幕上刷新的 ListView 部分无效显示。当您有要添加/删除的项目时,您只需重新发送LVM_SETITEMCOUNT。这是处理大量列表项的一种更快、更灵活的方法。

Using virtual lists

【讨论】:

  • 我创建了两个组,一个显示项目,另一个隐藏。现在我有一个问题,实际上我的隐藏组没有隐藏。更多信息附加到第一篇文章。
  • LVM_ENABLEGROUPVIEW 会自动取消 LVS_EX_GRIDLINES 吗?
  • @amaninlove 听起来像是一个值得单独发帖的问题。
猜你喜欢
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
  • 1970-01-01
  • 2011-06-21
相关资源
最近更新 更多