2010-11-10 3 views
2

Cela devrait être assez facile, mais je vais avoir un mal fou à le faire. Fondamentalement, je veux déplacer une ligne dans mon wxListCtrl haut ou bas. J'ai posté ceci au forum de wxwidgets et ai obtenu le code suivant.Comment déplacer un élément vers le haut et vers le bas dans un 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(); 

qui ne fonctionne pas. L'élément est supprimé mais pas déplacé (je suppose que la ligne setitem ne fonctionne pas). Ensuite, j'ai pensé à simplement changer le texte et l'image mais je ne peux même pas obtenir le texte de la rangée de manière fiable. J'ai

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

mais le texte est vide même s'il y a du texte et que l'index est correct. Donc, je suis coincé même pas capable de faire la tâche la plus basique. Quelqu'un sait-il comment faire cela? Le code s'exécute dans un rappel de bouton (l'utilisateur appuie sur une petite flèche vers le haut et mon code s'exécute pour essayer de le déplacer). J'utilise 2.9.1 sur Windows.

+0

Est-ce que ça marche dans 2.8.x? – genpfault

Répondre

0

La liste est-elle commandée? s'il s'agit d'une commande automatique, il se peut que vous ignoriez l'ordre que vous essayez d'appliquer.

De souvenir de l'ordre interne était pas nécessairement séquentielle, vous pourriez avoir à obtenir l'indice de l'élément précédent et aller un avant lui.

1

Je l'ai fait travailler comme ça avec 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(); 
} 

La chose que je remarqué que wxListItem est plus d'une struct commodité, pour stocker l'état de la vue et aide les valeurs de passe dans la wxListCtrl "bien". Il n'est en aucun cas lié à ce qui est réellement à l'intérieur de wxListCtrl.

Espérons que cela aidera tout le monde!

1

Même une réponse est déjà vérifiée. J'ai le même problème ici, mais ma liste n'est pas ordonnée. En examinant le code de wxWidgets, j'ai découvert qu'il y avait une autre information importante dans l'objet wxListItem - the mask. J'ai réorganisé mon travail en définissant la valeur du masque sur -1, ce qui signifie que toutes les données doivent être copiées. Cela inclut le texte de l'article ainsi que d'autres informations, comme les données de l'article (ce qui était important dans mon cas).

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 

J'ai également dû utiliser "InsertItem" au lieu de "SetItem". Sinon, aucun nouvel élément n'a été inséré, mais un élément existant a été remplacé (voir aussi tomcat31's answer).

Questions connexes