如何使Windows ListView控件和它们映射到的对象保持同步



我有几个窗口,其中包含映射到同一对象数组的列表视图控件。在我选一个之前,一切都很好。据我所知,这会更改项的索引(尽管试图强制iItem等于对象成员"id")。问题是,如果在更改默认排序后删除列表视图项,它会删除同一位置的其他控件中的项,还会断开对象之间的链接。例如,假设我默认的4个项目最初的顺序是A、B、C、D(在窗口1和窗口2中)。然后,我将窗口1中的控件重新排序为D、C、B、A并删除B。在窗口2中,项目C将被删除,因为它位于相同的位置。

我可以循环浏览比较文本的每个项目,但这似乎真的很低效。有没有办法将ListView项映射到一个不变的内部id?如果没有,有什么想法可以让这项工作在不经历太多困难的情况下发挥作用吗?

提前谢谢。

在虚拟模式下使用ListViews,并在请求时让它们从同一源数组中提取数据值。如果需要单独对ListView进行排序/操作,只需为每个ListView创建单独的数组,并使这些数组仅包含指向主数组元素的指针(或索引)。然后,您可以根据需要对每个ListView数组中的项进行排序和删除,而不会影响其他ListView,也不会浪费内存到处复制源数据。不要将实际数据存储在ListViews本身中。

例如:

std::vector<std::string> MainData(4);
Main[0] = "A";
Main[1] = "B";
Main[2] = "C";
Main[3] = "D";

std::vector<int> ListView1Data(MainData.size());
for (int i = 0; i < ListView1Data.size(); ++i)
ListView1Data[i] = i;
hListView1 = CreateWindowEx(..., LVS_OWNERDATA, ...);
ListView_SetItemCount(hListView1, ListView1Data.size()); 
...
case LVN_GETDISPINFO:
{
NMLVDISPINFO* pdi = reinterpret_cast<NMLVDISPINFO*>(lParam);
int index = ListView1Data[pdi->item.iItem];
if (pdi->item.mask & LVIF_TEXT)
strncpy(pdi->item.pszText, MainData[index].c_str(), pdi->item.cchTextMax);
...
break;
}

bool CompareListItems(int a, int b)
{
return MainData[a] < MainData[b];    
}
std::sort(ListView1Data.begin(), ListView1Data.end(), CompareListItems);
ListView_RedrawItems(hListView1, 0, ListView1Data.size());

ListView1Data.erase(ListView1Data.begin()+index);
ListView_SetItemCount(hListView1, ListView1Data.size()); 

如果你想删除一个ListView中的一个项目,并在其他ListView中删除相同的项目,而不管它们的本地排序如何,你也可以这样做:

int MainIndex = ListView1Data[index];
std::vector<int>::iterator iter = ListView1Data.begin()+index;
ListView2Data.erase(iter);
ListView_SetItemCount(hListView1, ListView1Data.size()); 
iter = std::find(ListView2Data.begin(), ListView2Data.end(), MainIndex);
ListView2Data.erase(iter);
ListView_SetItemCount(hListView2, ListView2Data.size()); 
iter = std::find(ListView3Data.begin(), ListView3Data.end(), MainIndex);
ListView3Data.erase(iter);
ListView_SetItemCount(hListView3, ListView3Data.size()); 
...

最棘手的部分是,是否也需要从主数组中删除相同的项。在这种情况下,您必须根据需要使用新的指针/索引更新每个ListView数组。在这种情况下,为每个主数组项提供一个唯一的ID,然后在每个ListView数组中跟踪该ID就开始有意义了。然后,每当需要访问该项的数据时,每个ListView都可以在主数组中查找ID。

最新更新