Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使Windows ListView控件与其映射到的对象保持同步?_C++_Windows_Winapi - Fatal编程技术网

C++ 如何使Windows ListView控件与其映射到的对象保持同步?

C++ 如何使Windows ListView控件与其映射到的对象保持同步?,c++,windows,winapi,C++,Windows,Winapi,我有几个窗口包含映射到同一对象数组的列表视图控件。在我对其中一个进行排序之前,一切正常。据我所知,这会更改项的索引(尽管试图强制iItem等于对象成员“id”)。问题是,如果在更改默认排序后删除列表视图项,它将删除位于同一位置的其他控件中的项,并且还会断开对象之间的链接。例如,假设我拥有的默认4项最初的顺序是A、B、C、D(在窗口1和窗口2中)。然后,我将窗口1中的控件重新排序为D、C、B、A和delete B。在窗口2中,项目C将被删除,因为它位于相同的位置 我可以循环浏览每一项,比较文本,但

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

我可以循环浏览每一项,比较文本,但这似乎真的很低效。是否仍要将ListView项映射到不会更改的内部id?如果不是的话,有没有关于如何在不经历太多困难的情况下实现这一点的想法


提前感谢。

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

例如:

std::vector<std::string> MainData(4);
Main[0] = "A";
Main[1] = "B";
Main[2] = "C";
Main[3] = "D";
如果要删除一个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()); 

...
int maindex=ListView1Data[index];
std::vector::iterator iter=ListView1Data.begin()+索引;
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。

使用LVITEM.lParam为该项提供唯一ID。或者对集合进行排序。是否可以向ListItem类添加“辅助”对象指针成员?通常,将ListItem索引用作其他任何内容的索引是一个坏主意,因为它们往往会发生变化:(@HansPassant LVITEM.lParam当然!谢谢你,效果很好。哇,谢谢你花时间为我写下所有这些。这太好了,因为我正在考虑如何消除所有冗余。我需要花一些时间来消化上面的内容,但我肯定会让你知道它是否有效。作为一名st阿特:还有。我还没有完全完成,但到目前为止它似乎在工作。但是,性能似乎受到了影响(列表视图项目需要更多的时间才能显示),这是违反直觉的,因为我认为使用虚拟列表会更快。虚拟列表视图非常快,因此任何减速都将与您管理数据的方式有关。使用探查器查找瓶颈。是的,它现在工作得非常快。我意外地将一些代码记录到LVN_GETDISPINFO中的一个文件,这导致了经济放缓。
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()); 
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()); 

...