2010-11-10 1 views
2

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

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

+0

Работает ли он в 2.8.x? – genpfault

ответ

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

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