在列表框中向上或向下移动项目
Move an item up or down in a list box
我有一个CListBox,我想有一个上移/下移按钮,可以向上或向下移动当前选择的项目。
现在,我认为唯一的解决方案是删除该项目,然后将其插入新位置。
有更有效的方法吗?
这是我10年前做的一个片段。它使用删除和添加来切换位置,但我认为这是唯一的方法。
void CKnoepfeDlg::OnDown()
{
int item = m_list.GetNextItem(-1,LVNI_SELECTED);
if(item == -1)
return;
if(item < m_list.GetItemCount() - 1)
{
CString name,befehl;
name = m_list.GetItemText(item,0);
befehl = m_list.GetItemText(item,1);
m_list.DeleteItem(item);
m_list.InsertItem(item + 1,name);
m_list.SetItemText(item + 1,1,befehl);
m_list.SetItemState(item + 1,LVNI_SELECTED,LVIS_SELECTED);
}
}
以下代码适用于Move Up。
void CStreamTable::OnBnClickedMoveUp()
{
int item = m_InputStreamListControl.GetNextItem(-1, LVNI_SELECTED);
if (item == -1)
return;
if (item > 0)
{
CString name, befehl;
name = m_InputStreamListControl.GetItemText(item, 0);
befehl = m_InputStreamListControl.GetItemText(item, 1);
m_InputStreamListControl.DeleteItem(item);
m_InputStreamListControl.InsertItem(item - 1, name);
m_InputStreamListControl.SetItemText(item - 1, 1, befehl);
m_InputStreamListControl.SetItemState(item - 1, LVNI_SELECTED, LVIS_SELECTED);
}
}
有点晚了,但这里有一个适用于MFC CListBox的有效解决方案
它支持多选,避免在所选项目到达顶部/底部时重新排序。
// --------------------------------------------------------------- //
// Move item with index 'item' one place up
// --------------------------------------------------------------- //
void CListBox_MoveItemUp(CListBox& box, int item) {
if(item <= 0) { return; }
CString oldstring;
box.GetText(item, oldstring);
DWORD_PTR olddata = box.GetItemData(item);
int oldsel = box.GetSel(item);
box.DeleteString(item);
item = box.InsertString(item-1, oldstring);
box.SetItemData(item, olddata);
box.SetSel(item, oldsel);
}
// --------------------------------------------------------------- //
// Move all items one place up, if there is space to move
// --------------------------------------------------------------- //
void CListBox_MoveSelectedItemsUp(CListBox& box, std::vector<INT> sels) {
std::sort(sels.begin(), sels.end());
// if 0 is selected, it might block all next selected items, too.
for(int i=0; !sels.empty(); ++i) {
if(sels.front() == i) {
sels.erase(sels.begin());
} else {
break;
}
}
for(int isel = 0; isel < int(sels.size()); ++isel) {
int item = int(sels[isel]);
CListBox_MoveItemUp(box, item);
}
}
// --------------------------------------------------------------- //
// Move item with index 'item' one place down
// --------------------------------------------------------------- //
void CListBox_MoveItemDown(CListBox& box, int item) {
if(item+1 >= box.GetCount()) { return; }
CString oldstring;
box.GetText(item, oldstring);
DWORD_PTR olddata = box.GetItemData(item);
int oldsel = box.GetSel(item);
box.DeleteString(item);
item = box.InsertString(item+1, oldstring);
box.SetItemData(item, olddata);
box.SetSel(item, oldsel);
}
// --------------------------------------------------------------- //
// Move all items one place down, if there is space to move
// --------------------------------------------------------------- //
void CListBox_MoveSelectedItemsDown(CListBox& box, std::vector<INT> sels) {
std::sort(sels.begin(), sels.end());
// if last is selected, it might block all previous selected items, too.
for(int i=box.GetCount()-1; !sels.empty(); --i) {
if(sels.back() == i) {
sels.pop_back();
} else {
break;
}
}
for(int isel = int(sels.size())-1; isel>=0; --isel) {
int item = int(sels[isel]);
CListBox_MoveItemDown(box, item);
}
}
//---------------------------------------------------------------//
// Move selected items up in the listbox
//---------------------------------------------------------------//
void MyDialog::OnBnClickedMoveUp() {
int nsel = m_MyListBox.GetSelCount();
if(!nsel) { return; }
std::vector<INT> selectedItems;
selectedItems.resize(nsel);
m_MyListBox.GetSelItems(nsel, &selectedItems[0]);
CListBox_MoveSelectedItemsUp(m_MyListBox, selectedItems);
}
//---------------------------------------------------------------//
// Move selected items down in the listbox
//---------------------------------------------------------------//
void MyDialog::OnBnClickedMoveDown() {
int nsel = m_MyListBox.GetSelCount();
if(!nsel) { return; }
std::vector<INT> selectedItems;
selectedItems.resize(nsel);
m_MyListBox.GetSelItems(nsel, &selectedItems[0]);
CListBox_MoveSelectedItemsDown(m_MyListBox, selectedItems);
}
相关文章:
- QTreeWidget 在移动项目时会回弹
- 如何有效地将(一些)项目从一个std::map移动到另一个std::map
- 将外部库"inside"项目中移动
- QListWidget 在用户选择项目时移动
- 如果我尝试将对话框从一个项目移动到另一个项目,我是否需要从 rc 文件中复制 DESIGNINFO、对话框信息和AFX_
- Qt 创建者在我将项目移动到另一个地方后仍然使用源项目
- 移动了 QT 项目,重命名文件夹和项目名称,Moc'ing 返回"'-I'之后缺少值"
- 将函数从控制台应用程序移动到共享库项目似乎会带来不相关的编译错误
- 将过滤器中的所有.cpp和.h移动到另一个项目并更正其文件夹位置
- 防止向量项目被移动
- 在项目中移动了文件,现在我找不到命名空间
- 移动 OpenCV Visual Studio 项目
- 在Visual Studio中,我不想提交我的Debug文件夹,但它中有dll文件,如果我移动它,项目将无法编译
- 将 Windows C++ 项目从 Qt4 移动到 5 会给出数百个看似无关的编译错误
- 如何有效地移动大量的图形项目
- 在列表框中向上或向下移动项目
- 用鼠标在QGraphicsView/QGraphicsScene上移动项目
- 对于C++项目,从Gradle移动到CMake
- 移动项目的平均值
- qt QAbstractItemModel 拖放用于移动项目执行删除/插入