2013-12-16 3 views
1

В диалоговом окне MFC я использовал CListCtrl с флажком. Я хочу отключить выбор нескольких флажков, чтобы пользователь мог выбрать только один флажок одновременно. Что является лучшим способом для достижения this.I сделали этотолько один выбор в CListCtrl Флажок в MFC

void SomeClass::OnClickList(NMHDR *pNMHDR, LRESULT *pResult) 
    { 
     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); 


     int nSelectedItemIndex = -1; 
     nSelectedItemIndex = m_ListCtrl.GetNextItem(-1, LVNI_SELECTED); 
     int nCount = m_ListCtrl.GetItemCount();  
     for(int nItem = 0; nItem < nCount; nItem++) 
     { 
      m_ListCtrl.SetCheck(nItem,false); 
     } 
     if(nSelectedItemIndex != -1) 
      m_ListCtrl.SetCheck(nSelectedItemIndex,true); 

     *pResult = 0; 
    } 

Как-то я думаю, что этот метод не так собственно и может быть лучше по-другому. Все предложения приветствуются.

EDIT: UPDATE: после написания кода все работает, но перед вами стоит новая проблема. вызов функции SetCheck() внутри функции обработчика сообщений OnItemChanged, она вызывает ту же функцию снова, создавая рекурсию. Таким образом, изменение выбора как-то медленное. Как этого избежать. Пожалуйста, помогите. ????

ответ

1

При создании элемента управления убедитесь, что этот стиль используется LVS_SINGLESEL.

Он передается в функции CreateEx/CreateEx. Также доступен редактор ресурсов (если через него добавлен элемент управления).

+1

Я проверил свойства listctrl из представления источника. Единственный выбор задан верно. Но все же я могу выбрать несколько флажков за раз. Возможно, я ошибался в своем вопросе, произнося несколько вариантов, на самом деле это проблема множественного выбора флажка. –

1

Наконец-то я решил. Теперь флажок и выбор выполняются по пар. выбор флажка выбирает строку и наоборот, и один выбор возможен. код:

void SomeClass::ResetAllCheckBox() 
    { 
     int nCount = m_ListCtrl.GetItemCount(); 
     for(int nItem = 0; nItem < nCount; nItem++) 
     { 
      m_ListCtrl.SetCheck(nItem,false); 
     } 

    } 

    //Handler for ON_NOTIFY(NM_CLICK,...) 
    void SomeClass::OnClickList(NMHDR *pNMHDR, LRESULT *pResult) 
    { 
     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); 
     NMLISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; 
     LVHITTESTINFO hitinfo; 
     int nPosCB=-1,nPos=-1; 
     hitinfo.pt = pNMListView->ptAction; 

     //Make the hit test... 
     nPosCB = m_ListCtrl.HitTest(&hitinfo); 

     if(hitinfo.flags != LVHT_ONITEMSTATEICON) 
      return; 
     ResetAllCheckBox(); 

     nPos = m_ListCtrl.GetNextItem(-1,LVNI_SELECTED); 
     m_ListCtrl.SetItemState(nPos, ~LVIS_SELECTED, LVIS_SELECTED); 
     m_ListCtrl.SetItemState(nPosCB, LVIS_SELECTED, LVIS_SELECTED); 
     m_ListCtrl.SetSelectionMark(nPosCB); 
     *pResult = 0; 
    } 


    //Handler for ON_NOTIFY(LVN_ITEMCHANGED,...) 
    void SomeClass::OnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult) 
    { 
     LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); 
     int nPos = -1; 

     ResetAllCheckBox(); 

     nPos = m_ListCtrl.GetNextItem(-1,LVNI_SELECTED); 
     if(nPos != -1) 
      m_ListCtrl.SetCheck(nPos); 

     int nCount = m_ListCtrl.GetItemCount(); 
     int nSelectedItemIndex = -1; 
     for(int nItem = 0; nItem < nCount; nItem++) 
     { 
      if(m_ListCtrl.GetCheck(nItem)== 1) 
       nSelectedItemIndex = nItem; 
     } 

     *pResult = 0; 
    }