【问题标题】:Move an item up or down in a list box在列表框中向上或向下移动项目
【发布时间】:2012-08-22 07:43:53
【问题描述】:

我有一个 CListBox,我想有一个上移/下移按钮,用于将当前选定的项目向上或向下移动。

现在我认为唯一的解决方案是删除该项目,然后将其插入新位置。

有没有更有效的方法?

【问题讨论】:

  • 有些东西here 可能会有所帮助

标签: c++ winapi mfc clistbox


【解决方案1】:

这是我 10 年前制作的一个 sn-p。它使用删除和添加来切换位置,但我认为这是唯一的方法。

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

【讨论】:

  • 上面的代码是针对 CListCtrl 而不是针对 CListBox!
【解决方案2】:

以下代码适用于 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);
       }
    }

【讨论】:

    【解决方案3】:

    有点晚了,但这是 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多