MFC listcontrol 分列 添加行数据 点击列头排序
适用于 对话框程序
1.在工具箱中拖出 ListControl,然后右键-属性,view-Report
让你的ListControl变成这幅模样!
2.添加ListControl控件的control类型变量(如:List,下文中要用到)
3.分列并添加点击选中一行的属性()
List.DeleteAllItems();//先清空 //set the list's titles TCHAR rgtsz[6][15] = { _T("学号"), _T("姓名"),_T("性别"), _T("程序设计得分"), _T("高等数学得分")}; LV_COLUMN lvcolumn; CRect rect; List.GetWindowRect(&rect);//获取list的宽度 for (int i = 0; i<5; i++) { lvcolumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH | LVCF_ORDER; lvcolumn.fmt = LVCFMT_LEFT; lvcolumn.pszText = rgtsz[i]; lvcolumn.iSubItem = i; lvcolumn.iOrder = i; lvcolumn.cx = rect.Width() / 5;//设定列头的宽度 List.InsertColumn(i, &lvcolumn);//有这行代码,才能将列添加进list }
//添加这行代码可以实现选中List中的一行 List.SetExtendedStyle(List.GetExtendedStyle() | LVS_EX_FULLROWSELECT);
List.SetRedraw(TRUE);//显示
4.在listcontrol属性中找到控件事件NM_CLICK 添加函数,这样可以实现单击一行即可选中。
5.在该函数中添加代码
void CStudentManagementDlg::OnNMClickList2(NMHDR *pNMHDR, LRESULT *pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 *pResult = 0; POSITION pos = List.GetFirstSelectedItemPosition(); if (pos == NULL) return; CString temp; // 选择语言的名称字符串 NMLISTVIEW *listItem = (NMLISTVIEW*)pNMHDR; if (-1 != listItem->iItem) // 如果iItem不是-1,就说明有列表项被选择 { temp = List.GetItemText(listItem->iItem, 2);//取出选中行里的列数据,这里取的是第三列,第一列从0开始 // 将选择的语言显示与编辑框中 SetDlgItemText(IDC_EDIT1, temp); } }
6.为listcontrol的控件事件LVN_COLUMNCLICK添加函数,这样可以实现点击列头,并获取列数
7.在该函数中添加
void CStudentManagementDlg::OnLvnColumnclickList2(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 manage.sortColumn = pNMLV->iSubItem;//获取点击的列 //添加自己的排序代码,最后再刷新控件内容 *pResult = 0; }
8.添加list行数据
List.InsertItem(j, temp);//j为行数,temp为CString
List.SetItemText(j, 0, temp);//j依旧为行数,0是列数,列从0开始计数,temp为显示的CString字符串
附上一个很劣质的实例
// StudentManagementDlg.cpp : 实现文件 // #include "stdafx.h" #include "StudentManagement.h" #include "StudentManagementDlg.h" #include "afxdialogex.h" #include "Management.h" #include "HelpDlg.h" #include "windows.h" #ifdef _DEBUG #define new DEBUG_NEW #endif ///////////////////////////////////////////////////////////////////////////////////////////// Management manage; ///////////////////////////////////////////////////////////////////////////////////////////// // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ABOUTBOX }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() public: afx_msg void OnStnClickedMainframe(); }; CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) ON_STN_CLICKED(IDR_MAINFRAME, &CAboutDlg::OnStnClickedMainframe) END_MESSAGE_MAP() // CStudentManagementDlg 对话框 CStudentManagementDlg::CStudentManagementDlg(CWnd* pParent /*=NULL*/) : CDialogEx(IDD_STUDENTMANAGEMENT_DIALOG, pParent) , studentNumber(0) , studentName(_T("")) , studentCppScore(0) , studentMathScore(0) , isMale(FALSE) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CStudentManagementDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, studentNumber); DDX_Text(pDX, IDC_EDIT2, studentName); DDV_MaxChars(pDX, studentName, 10); DDX_Text(pDX, IDC_EDIT3, studentCppScore); DDX_Text(pDX, IDC_EDIT4, studentMathScore); DDX_Radio(pDX, IDC_RADIO1, isMale); DDX_Control(pDX, IDC_LIST2, showStudentList); DDX_Control(pDX, IDC_EDIT1, studentNumberEdit); DDX_Control(pDX, IDC_EDIT2, studentNameEdit); DDX_Control(pDX, IDC_EDIT3, studentCppScoreEdit); DDX_Control(pDX, IDC_EDIT4, studentMathScoreEdit); } BEGIN_MESSAGE_MAP(CStudentManagementDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_GETMINMAXINFO() // ON_BN_CLICKED(IDOK, &CStudentManagementDlg::OnBnClickedOk) ON_BN_CLICKED(IDCANCEL, &CStudentManagementDlg::quitApp) ON_BN_CLICKED(IDC_BUTTON3, &CStudentManagementDlg::addStudent) ON_BN_CLICKED(IDC_BUTTON2, &CStudentManagementDlg::deleteStudent) ON_BN_CLICKED(IDC_BUTTON1, &CStudentManagementDlg::alterStudentInfo) ON_EN_CHANGE(IDC_EDIT1, &CStudentManagementDlg::OnEnChangeEditNumber) ON_EN_CHANGE(IDC_EDIT2, &CStudentManagementDlg::OnEnChangeEditName) ON_EN_CHANGE(IDC_EDIT3, &CStudentManagementDlg::OnEnChangeEditCpp) ON_EN_CHANGE(IDC_EDIT4, &CStudentManagementDlg::OnEnChangeEditMath) //ON_BN_CLICKED(IDOK, &CStudentManagementDlg::refreshList) ON_BN_CLICKED(IDC_RADIO1, &CStudentManagementDlg::OnBnClickedRadio1) ON_BN_CLICKED(IDC_RADIO2, &CStudentManagementDlg::OnBnClickedRadio2) ON_NOTIFY(NM_CLICK, IDC_LIST2, &CStudentManagementDlg::OnNMClickList2) ON_NOTIFY(NM_CLICK, IDC_LIST2, &CStudentManagementDlg::OnNMClickList2) ON_BN_CLICKED(IDOK2, &CStudentManagementDlg::showGraph) ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST2, &CStudentManagementDlg::OnLvnColumnclickList2) ON_BN_CLICKED(IDC_BUTTON4, &CStudentManagementDlg::OnBnClickedButton4) ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, &CStudentManagementDlg::OnLvnItemchangedList2) END_MESSAGE_MAP() // CStudentManagementDlg 消息处理程序 //弹出对话框时就会执行的函数,如果需要对话框在打开时就进行某些初始化,就在这里进行修改 BOOL CStudentManagementDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 ShowWindow(SW_NORMAL); // TODO: 在此添加额外的初始化代码 ///////////////////////////////////////////////////////////////////////////////////////////// //清空列表内容 showStudentList.DeleteAllItems(); //定义要用到的标题名 TCHAR rgtsz[6][15] = { _T("学号"), _T("姓名"),_T("性别"), _T("程序设计得分"), _T("高等数学得分")}; LV_COLUMN lvcolumn; CRect rect; //获取列表的宽高 showStudentList.GetWindowRect(&rect); for (int i = 0; i<5; i++) { //设置列表头的显示风格 lvcolumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH | LVCF_ORDER; lvcolumn.fmt = LVCFMT_LEFT; //设置列表头显示的标题 lvcolumn.pszText = rgtsz[i]; lvcolumn.iSubItem = i; //设置第几列,第一列为0 lvcolumn.iOrder = i; //每一列的宽度 lvcolumn.cx = rect.Width() / 5; //向列表写入配置好的这一列 showStudentList.InsertColumn(i, &lvcolumn); } //添加可以选中列表中的某一行的功能 showStudentList.SetExtendedStyle(showStudentList.GetExtendedStyle() | LVS_EX_FULLROWSELECT); //在外部读取文件进来 manage.getData(); //自定义的刷新函数 refreshList(); //重绘这个列表 showStudentList.SetRedraw(TRUE); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CStudentManagementDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; //弹出关于框 dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CStudentManagementDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CStudentManagementDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } ///////////////////////////////////////////////////////////////////////////////////////////// void CStudentManagementDlg::OnEnChangeEditNumber() { } void CStudentManagementDlg::OnEnChangeEditName() { } void CStudentManagementDlg::OnEnChangeEditCpp() { } void CStudentManagementDlg::OnEnChangeEditMath() { } ///////////////////////////////////////////////////////////////////////////////////////////// //将刷新列表的代码定义为函数,方便多次进行列表刷新 void CStudentManagementDlg::refreshList() { manage.sortData(manage.sortColumn); showStudentList.DeleteAllItems(); showStudentList.SetRedraw(FALSE); vector<Student>::iterator it; int j = 0; for (it = manage.vec.begin(); it != manage.vec.end(); it++,j++) { CString temp; temp.Format("%lld",it->number); //开始插入行数据 showStudentList.InsertItem(j, temp); //参数列表(行,列,要显示的内容) showStudentList.SetItemText(j, 0, temp); showStudentList.SetItemText(j, 1, it->name); if(it->isMale) showStudentList.SetItemText(j, 2, "男"); else showStudentList.SetItemText(j, 2, "女"); temp.Format("%lf", it->cppScore); showStudentList.SetItemText(j, 3,temp); temp.Format("%lf", it->mathScore); showStudentList.SetItemText(j, 4, temp); } showStudentList.SetRedraw(TRUE); } int CStudentManagementDlg::isValidInput() { if (studentCppScore < 0 || studentCppScore >100 || studentMathScore < 0 || studentMathScore > 100) { AfxMessageBox(_T("有效的分数范围为:0 - 100!\n如有疑问,请查看使用说明。")); return 1; } if (studentNumberEdit.GetWindowTextLengthA() > 18) { AfxMessageBox(_T("学号位数应小于19位!\n如有疑问,请查看使用说明。")); return 1; } if (studentNameEdit.GetWindowTextLengthA() == 0) { AfxMessageBox(_T("请输入姓名!")); return 1; } if (studentCppScoreEdit.GetWindowTextLengthA() == 0 || studentMathScoreEdit.GetWindowTextLengthA() == 0) { AfxMessageBox(_T("请输入分数!")); return 1; } if (studentNumberEdit.GetWindowTextLengthA() == 0) { AfxMessageBox(_T("请输入学号!")); return 1; } return 0; } void CStudentManagementDlg::addStudent() { UpdateData(TRUE); if (isValidInput() > 0) return; if (manage.add(studentName, studentNumber, studentCppScore, studentMathScore, isMale)) { if (MessageBox("此学生数据已存在,是否修改数据?", "警告", MB_ICONEXCLAMATION | MB_OKCANCEL) == IDCANCEL) return; if (manage.change(studentName, studentNumber, studentCppScore, studentMathScore, isMale)) AfxMessageBox(_T("修改失败")); } else AfxMessageBox(_T("添加成功")); refreshList(); } void CStudentManagementDlg::alterStudentInfo() { UpdateData(TRUE); if (isValidInput() > 0) return; if (manage.change(studentName, studentNumber, studentCppScore, studentMathScore, isMale)) AfxMessageBox(_T("修改失败")); refreshList(); } void CStudentManagementDlg::deleteStudent() { UpdateData(TRUE); //判定编辑框里的内容是否为空。studentNumberEdit为编辑框的control类型的变量 if (studentNumberEdit.GetWindowTextLengthA() == 0) { AfxMessageBox(_T("请输入要删除的学生的学号!")); return; } //MessageBox("提示框显示的内容", "提示框标题", MB_ICONEXCLAMATION | MB_OKCANCEL) == IDCANCEL,IDCANCEL表示点击了取消 if (MessageBox("确定删除此学生数据?", "警告", MB_ICONEXCLAMATION | MB_OKCANCEL) == IDCANCEL) return; if (manage.del(studentNumber)) AfxMessageBox(_T("删除失败!")); refreshList(); } void CStudentManagementDlg::showGraph() { manage.save(); //打开另一个程序 WinExec("C:\\ShowStudentScore.exe",SW_SHOW); } void CStudentManagementDlg::quitApp() { //AfxMessageBox(_T("Exiting")); manage.save(); CDialogEx::OnCancel(); } void CStudentManagementDlg::OnBnClickedRadio1() { // TODO: 在此添加控件通知处理程序代码 isMale = TRUE; } void CStudentManagementDlg::OnBnClickedRadio2() { // TODO: 在此添加控件通知处理程序代码 isMale = FALSE; } //select a line in the listcontrol void CStudentManagementDlg::OnNMClickList2(NMHDR *pNMHDR, LRESULT *pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 *pResult = 0; //获取点击的行的位置,showStudentList为列表的control类型变量 POSITION pos = showStudentList.GetFirstSelectedItemPosition(); if (pos == NULL) return; CString temp; NMLISTVIEW *listItem = (NMLISTVIEW*)pNMHDR; if (-1 != listItem->iItem) // 如果iItem不是-1,就说明有列表项被选择 { //GetItemText(点击的行数, 该行的列数)获取对应列的内容 temp = showStudentList.GetItemText(listItem->iItem, 2); if (!temp.Compare("男")) isMale = TRUE; else isMale = FALSE; UpdateData(FALSE); // 获取被选择列表项第一个子项的文本 temp = showStudentList.GetItemText(listItem->iItem, 0); // 将选择的语言显示与编辑框中 SetDlgItemText(IDC_EDIT1, temp); temp = showStudentList.GetItemText(listItem->iItem, 1); SetDlgItemText(IDC_EDIT2, temp); temp = showStudentList.GetItemText(listItem->iItem, 3); SetDlgItemText(IDC_EDIT3, temp); temp = showStudentList.GetItemText(listItem->iItem, 4); SetDlgItemText(IDC_EDIT4, temp); } } void CStudentManagementDlg::OnLvnColumnclickList2(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 manage.sortColumn = pNMLV->iSubItem;//点击的列 if (!(manage.sortColumn == 0 || manage.sortColumn == 3 || manage.sortColumn == 4)) return; if (manage.sortColumn == 0 || manage.sortColumn == 3 || manage.sortColumn == 4) manage.sortData(manage.sortColumn); *pResult = 0; refreshList(); CString msg; msg.Format("%s",manage.sortColumn == 0 ? "列表内容已根据学号成绩排列! (由小到大的顺序)" : (manage.sortColumn == 3 ? "列表内容已根据程序设计成绩排列! (由高到低的顺序)" : "列表内容已根据高等数学成绩排列! (由高到低的顺序)")); AfxMessageBox(msg); } void CAboutDlg::OnStnClickedMainframe() { // TODO: 在此添加控件通知处理程序代码 } void CStudentManagementDlg::OnBnClickedButton4() { // TODO: 在此添加控件通知处理程序代码 HelpDlg help; help.DoModal(); } void CStudentManagementDlg::OnGetMinMaxInfo(MINMAXINFO *lpMMI) { CPoint pt(320, 1250); //定义宽和高 lpMMI->ptMinTrackSize = pt; //限制最小宽和高 CDialog::OnGetMinMaxInfo(lpMMI); } void CStudentManagementDlg::OnLvnItemchangedList2(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 *pResult = 0; }
Stay hungry,stay foolish.