【发布时间】:2014-09-05 13:35:27
【问题描述】:
目前我正在研究一个列表控件,其中第一列标题应包含一个复选框。可以通过将样式设置为 LVS_EX_CHECKBOXES 来向列表项添加复选框。有没有办法将复选框添加到标题中,以便如果我选中它,列表中的所有项目都应该被选中,如果我取消选中它,所有列表项都应该被取消选中。
谁能告诉我任何可能的方法。
【问题讨论】:
标签: visual-c++ mfc
目前我正在研究一个列表控件,其中第一列标题应包含一个复选框。可以通过将样式设置为 LVS_EX_CHECKBOXES 来向列表项添加复选框。有没有办法将复选框添加到标题中,以便如果我选中它,列表中的所有项目都应该被选中,如果我取消选中它,所有列表项都应该被取消选中。
谁能告诉我任何可能的方法。
【问题讨论】:
标签: visual-c++ mfc
按照以下步骤获取标题上的复选框,并使用标题上的复选框,我们可以选中和取消选中列表中的所有项目。
在 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 操作系统以上。
【讨论】:
CListCtrl/CHeaderCtrl,但不是CMFCListCtrl/CMFCHeaderCtrl! GRRRRR
CMFCListCtrl/CMFCHeaderCtrl 的标头上有一个复选框的功能甚至没有实现,因为我没有发现 @987654332 的出现@、HDF_CHECKBOX 和 HDF_CHECKED 在 afxheaderctrl.cpp|h 和 afxlistctrl.cpp|h 文件上!
接受的答案非常有帮助,但使用 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);
【讨论】: