2014-09-02 3 views
2

Я создал довольно стандартный ListView.C++ 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); 

после того, как я instert пункты и подпункты

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); 

Теперь я хотел бы реализовать какой-то поиск/фильтрация. Я вижу, что многие люди рекомендуют удалять/повторно вводить элементы, однако, поскольку в моем списке очень много элементов, это не лучшее решение. В то время как googling я узнал, что должно быть возможно установить groupid и установить состояние элемента (скрыть его). Однако я не уверен, как это сделать, скажем, у меня есть 10 элементов в моем списке, и я хочу скрыть некоторые элементы, как именно я это делаю?

EDIT:

Я поставил 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); 

Теперь я добавил некоторые элементы в обеих группах, только проблема в том, что я могу видеть их обоих (они разделены), а другой должен быть скрыт.

+0

Попробуйте добавить '' LVGS_NOHEADER' и LVGS_COLLAPSED' в 'state' второй группы. По-видимому, просто установка 'LVGS_HIDDEN' скрывает заголовок группы, но не элементы в группе, но если вы свернете« скрытую »группу, то ее элементы не будут видны. –

+0

Спасибо, это сработало. Однако изменение группы не быстрее, чем добавление элементов, и да, я сделал все оптимизации, как для изменения идентификатора только для элементов, которые меняют группу. За ~ 40 000 предметов это может занять более минуты, поэтому я действительно попробую Виртуальные списки. – Dan

ответ

6

Использование 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, вам обычно лучше использовать ListView в virtual mode. Вы можете предварительно фильтровать свои данные по мере необходимости, а затем использовать LVM_SETITEMCOUNT, чтобы указать количество элементов, которые хотите отобразить, а затем обрабатывать LVN_GETDISPINFO для извлечения данных для определенных элементов, когда ListView запрашивает их у вас. Таким образом, вы можете выполнить весь поиск/фильтрацию в своем источнике данных напрямую (в памяти, в базе данных и т. Д.), А затем просто аннулировать части ListView, которые необходимо обновить на экране, используя LVM_REDRAWITEMS, когда у вас есть новые данные для отображения , Когда у вас есть элементы для добавления/удаления, вы просто пересылаете LVM_SETITEMCOUNT. Это гораздо более быстрый и гибкий способ обработки множества элементов списка.

Using virtual lists

+0

Я создал две группы, которые показывают предметы и другие, которые скрываются. Теперь у меня проблема, что на самом деле моя скрытая группа не скрыта. Дополнительная информация добавлена ​​к первому сообщению. – Dan

Смежные вопросы