2009-09-22 12 views
27

Chcę wykonać kod, gdy użytkownik wybierze wiersz w CListCtrl (widok raportu, nie obchodzi mnie inny tryb przeglądania).Jak wykryć zmianę wyboru CListCtrl?

Jak złapać to wydarzenie? czy jest jakaś wiadomość, którą mogę zmapować lub taką metodę jak "OnSelectionChanged" czy coś w tym stylu?

Odpowiedz

38

Sponsorowane:

BEGIN_MESSAGE_MAP(cDlgRun, CDialog) 
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, OnItemchangedList2) 
END_MESSAGE_MAP() 

/* ... */ 

void cDlgRun::OnItemchangedList2(NMHDR* pNMHDR, LRESULT* pResult) 
{ 
    NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 

    if ((pNMListView->uChanged & LVIF_STATE) 
     && (pNMListView->uNewState & LVIS_SELECTED)) 
    { 
     // do stuff... 
    } 
} 
+1

To nie złapie się zmieniać, gdy wybierasz trzy elementy z przesunięciem, ale następnie wybierasz dowolne z nich (które odznacza pozostałe dwa, ale utrzymuje ten zaznaczony). Jakiekolwiek obejście tego problemu z wyjątkiem zachowania listy wybranych elementów? –

+0

Nie mogę przetestować go teraz, ale myślę, że będziesz musiał złapać zaznaczenie, jak również zaznaczenie: aby złapać zaznaczenie, użyj 'if ((pNMListView-> uChanged & LVIF_STATE) && (pNMListView-> uOldState & LVNI_SELECTED) &&! (PNMListView -> uNewState i LVNI_SELECTED)) ' – djeidot

+2

@djeidot: Dziękuję bardzo, pomogło. Po osadzeniu w swojej własnej klasie Kontroli, można to również zredukować do ON_NOTIFY_REFLECT (LVN_ITEMCHANGED, i OnItemSelected). – mox

4

djeidot ma rację w sprawie.

Po prostu chcę dodać, że nie ma OnSelectionChanged(), ponieważ ListView obsługuje selekcji wielokrotnej (choć można to wyłączyć). Dlatego lista pojedynczego wyboru wyśle ​​dwa zdarzenia: Stary element niezaznaczony I Nowy element wybrany.

9

Istnieje kilka powiadomień na podstawie tego, co się dzieje.

Jeśli wybierzesz element i nic jeszcze nie zostanie wybrane, otrzymasz jedno powiadomienie o zmianie LVIF_STATE: uNewState & LVIS_SELECTED. Nowo wybrany element będzie znaleźć na stronie:

pNMListView->iItem 

Jeśli element jest zaznaczony przed wybraniem nowego obiektu, dostaniesz trzy zmiany Stan:

pierwsze zostaniesz poinformowany, że w poprzednim punkcie ostrości utraty ostrości:

pNMListView->uOldState & LVIS_FOCUSED 

Następnie użytkownik zostanie powiadomiony, że stary element jest odznaczone:

pNMListView->uOldState & LVIS_SELECTED 

Wreszcie, otrzymasz nowy stan wyboru produktu:

pNMListView->uNewState & LVIS_SELECTED 

(ponownie spojrzeć na iItem dla nowo wybranego elementu)

Więc pułapka my biegł jest to, że z powodu wyników poz cofnięcie w dwóch zawiadomień , robiliśmy wiele powtarzalnych, czasem szkodliwych, przetwarzania. Ostatecznie wykonaliśmy to przetwarzanie tylko dla drugiej wiadomości (pNMListView->uOldState & LVIS_SELECTED) i pomijamy to samo przetwarzanie po utracie powiadomienia o fokucie.

-1

Na moim Visual Studio 2010, edytor wizualny deklaruje zwrotnego w oknie pliku nagłówka jak poniżej:

afx_msg void OnLbnSelchangeListOnvif(); 

oraz w pliku źródłowym:

BEGIN_MESSAGE_MAP(CDialogOnvif, CDialog) 
    ON_LBN_SELCHANGE(IDC_LIST_ONVIF, &CDialogOnvif::OnLbnSelchangeListOnvif) 
END_MESSAGE_MAP() 

void CDialogOnvif::OnLbnSelchangeListOnvif() 
{ 
    // do stuff... 
} 
+2

To będzie działać tylko dla List Boxes (CListBox), a nie CListCtrl. –

Powiązane problemy