Как переместить элемент вверх и вниз в wxListCtrl (wxwidgets) - PullRequest
2 голосов
/ 10 ноября 2010

Это должно быть довольно легко, но у меня чертовски много времени на это.По сути, я хочу переместить строку в моем 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();

, но текст пустой, хотя текст есть, а индекс правильный.Так что я застрял даже не в состоянии выполнить самую основную задачу.Кто-нибудь знает, как это сделать?Код выполняется в режиме обратного вызова кнопки (пользователь нажимает маленькую стрелку вверх, и мой код выполняется, чтобы попытаться переместить его).Я использую 2.9.1 на Windows.

Ответы [ 3 ]

1 голос
/ 23 января 2012

Я сделал так, чтобы это работало с 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 голос
/ 02 июля 2012

Даже ответ уже проверен. У меня та же проблема, но мой список неупорядочен. Просматривая код wxWidgets, я обнаружил, что внутри объекта wxListItem есть еще одна важная информация - маска . Я сделал так, чтобы мой порядок работал правильно, установив значение маски на -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 ).

0 голосов
/ 11 ноября 2010

Список упорядочен? если это автоматический заказ, возможно, он игнорирует заказ, который вы пытаетесь применить.

Исходя из воспоминаний, внутренний порядок не обязательно был последовательным, возможно, вам придется получить индекс предыдущего элемента и перейти на один перед ним.

...