如何在wxListCtrl中上下移动项目(wxwidgets)

时间:2010-11-10 20:14:59

标签: c++ windows wxwidgets

这应该很简单,但我很难做到这一点。基本上我想在我的wxListCtrl中向上或向下移动一行。我把它发布到wxwidgets论坛并获得以下代码。

m_list->Freeze(); 
wxListItem item; 
item.SetId(item_id); // the one which is selected 
m_list->GetItem(item); // Retrieve the item 
m_list->DeleteItem(item_id); // Remove it 
item.SetId(item_id - 1); // Move it up 
m_list->SetItem(item); // Apply it's new pos in the list 
m_list->Thaw();

哪个不起作用。元素被删除但没有向上移动(我猜setitem行不起作用)。然后我想只是切换文本和图像,但我甚至无法可靠地从行中获取文本。我有

int index = m_right->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
wxString label = m_right->GetItemText(index);

if(index == 0)
  return;

wxListItem item; 
item.SetId(index); 
bool success = m_right->GetItem(item); 
wxString text = item.GetText();

但即使文本和索引正确,文本仍为空白。所以,我甚至无法完成最基本的任务。有人知道怎么做吗?代码在按钮回调中运行(用户按下向上箭头,我的代码执行以尝试移动它)。我在Windows上使用2.9.1。

3 个答案:

答案 0 :(得分:1)

我用wxWidgets 2.9.3开始这样工作:

void FileSelectionPanel::OnMoveUp( wxCommandEvent& WXUNUSED(evt) )
{
    int idx = _listCtrl->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
    if( idx == 0) idx = _listCtrl->GetNextItem( 0, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );

    _listCtrl->Freeze();
    while( idx > -1 ) {    
        wxListItem item;
        item.SetId(idx); _listCtrl->GetItem(item);
        item.SetId(idx-1); _listCtrl->InsertItem(item);

        _listCtrl->SetItemData( idx-1, _listCtrl->GetItemData( idx+1 ));
        for( int i = 0; i < _listCtrl->GetColumnCount(); i++ ) {
            _listCtrl->SetItem( idx-1, i, _listCtrl->GetItemText( idx+1, i ));
        }
        _listCtrl->DeleteItem( idx + 1 );
        idx = _listCtrl->GetNextItem( idx-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
    }
    _listCtrl->Thaw();
}

我注意到wxListItem更像是一个方便结构,用于存储视图状态并帮助将值传递到wxListCtrl“很好”。它决不局限于wxListCtrl中的实际内容。

希望这对任何人都有帮助!

答案 1 :(得分:1)

即使已经有一个已经检查过的答案。我在这里有同样的问题,但我的清单是无序的。通过查看wxWidgets的代码,我发现wxListItem对象中还有另一个重要信息 - the mask。我通过将掩码值设置为-1使我的重新排序正常工作,这意味着所有数据都将被复制。这包括项目文本以及其他信息,例如项目数据(在我的情况下这很重要)。

wxListItem item;
item.SetId(item_id);         // set needed id
item.SetMask(-1);            // set needed data
m_list->GetItem(item);       // actually retrieve the item
m_list->DeleteItem(item_id); // remove old copy
item.SetId(item_id - 1);     // move item up
m_list->InsertItem(item);    // insert copy of item

我还必须使用“InsertItem”而不是“SetItem”。否则,没有插入新项目,但是现有的项目被覆盖(另请参阅tomcat31's answer)。

答案 2 :(得分:0)

是否订购了清单?如果是自动订购,则可能忽略了您尝试申请的订单。

从回忆中,内部顺序不一定是连续的,你可能必须获得前一项的索引并在它之前去一个。