如何在 listcontrol 列标题中添加一个复选框以选中和取消选中列表项的所有复选框?

Posted

技术标签:

【中文标题】如何在 listcontrol 列标题中添加一个复选框以选中和取消选中列表项的所有复选框?【英文标题】:How to add a checkbox to the listcontrol column header to check and uncheck all checkboxes of the list items? 【发布时间】:2014-09-05 13:35:27 【问题描述】:

目前我正在研究一个列表控件,其中第一列标题应包含一个复选框。可以通过将样式设置为 LVS_EX_CHECKBOXES 来向列表项添加复选框。有没有办法将复选框添加到标题中,以便如果我选中它,列表中的所有项目都应该被选中,如果我取消选中它,所有列表项都应该被取消选中。

谁能告诉我任何可能的方法。

【问题讨论】:

【参考方案1】:

按照以下步骤获取标题上的复选框,并使用标题上的复选框,我们可以选中和取消选中列表中的所有项目。

在 OnInitDialog() 中添加以下代码:

BOOL OnInitDialog()

    LVCOLUMN pColumn = 0;
   pColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

   m_listCtrl.GetColumn(0, &pColumn);
   pColumn.fmt |= HDF_CHECKBOX;
   pColumn.pszText = L"";
   pColumn.cx = 25;
   pColumn.iSubItem = 1;

   m_listCtrl.InsertColumn(1, &pColumn);//m_listctrl is listcontrol member variable


添加此事件 HDN_ITEMSTATEICONCLICK

   void CMFPSearchListView::OnHdnItemStateIconClickListctrl(NMHDR *pNMHDR, LRESULT *pResult)

    LPNMHEADER pNMHeader = (LPNMHEADER)pNMHDR;

    // first determine whether the click was a checkbox change
    if (pNMHeader->pitem->mask & HDI_FORMAT && pNMHeader->pitem->fmt & HDF_CHECKBOX)
    
        // now determine whether it was checked or unchecked
        BOOL bUnChecked = pNMHeader->pitem->fmt & HDF_CHECKED;

        // apply check state to each list item
        for (int nItem = 0; nItem < m_listCtrl.GetItemCount(); nItem++)
            m_listCtrl.SetCheck(nItem, !bUnChecked);
    


   *pResult = 1;   //if pResult = 0 then you will get blue color selection on the items when you check header checkbox , in order to avoid that I made pResult = 1; Now we won't face the selection issue.
    

//添加LVN_ITEMCHANGED

void OnListViewItemchanged(NMHDR *pNMHDR, LRESULT *pResult)

LVCOLUMN pColumn = 0;
pColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
m_listCtrl.GetColumn(0, &pColumn);
if(blAllChecked)
    pColumn.fmt |= HDF_CHECKED;
else
    pColumn.fmt &= ~HDF_CHECKED;


//m_listCtrl.InsertColumn(1, &pColumn);
m_listCtrl.SetColumn(0, &pColumn);
*pResult=0;    

注意:此标题复选框适用于 Windows XP 操作系统以上。

【讨论】:

也许这会更好地改写为““将在 Windows Vista 操作系统中开始工作”。 我在neowin.net/forum/topic/819824-c-listview 上报告了这个问题:如果没有扩展样式 LVS_EX_AUTOCHECKSELECT,标题上的复选框不会出现,我不想拥有它。 另一个观察结果:组合框出现在CListCtrl/CHeaderCtrl,但不是CMFCListCtrl/CMFCHeaderCtrl! GRRRRR 除了我之前的评论之外,很有可能在 CMFCListCtrl/CMFCHeaderCtrl 的标头上有一个复选框的功能甚至没有实现,因为我没有发现 @987654332 的出现@、HDF_CHECKBOXHDF_CHECKEDafxheaderctrl.cpp|hafxlistctrl.cpp|h 文件上! ***.com/a/41205752/383779我的问题解决了我的问题!【参考方案2】:

接受的答案非常有帮助,但使用 LVCOLUMN 对我来说效果不佳。

所以我发现使用 HDITEM 对我来说效果更好:

CHeaderCtrl* pHeaderControl = m_ListControl.GetHeaderCtrl();

HDITEM hdi =  0 ;
hdi.mask   = HDI_FORMAT;
pHeaderControl->GetItem(0, &hdi);
hdi.fmt |= HDF_CHECKBOX;

if (bAllChecked)

    hdi.fmt |= HDF_CHECKED;

else

    hdi.fmt &= ~HDF_CHECKED;

pHeaderControl->SetItem(0, &hdi);

【讨论】:

以上是关于如何在 listcontrol 列标题中添加一个复选框以选中和取消选中列表项的所有复选框?的主要内容,如果未能解决你的问题,请参考以下文章

猎豹MFC--列表控件ListControl

VC6.0中 如何将 LIST control中的信息读取到文本编辑框中

如何从 ListControl(ListView) 中检索数据?

VC++如何在多列中添加复选框

设置 DevExpress ComboBox 的 ListControl 的高度

在对话框窗口中使用 ListControl