MFC listcontrol 分列 添加行数据 点击列头排序

时间:2023-03-09 13:02:04
MFC listcontrol 分列 添加行数据 点击列头排序

适用于 对话框程序

1.在工具箱中拖出 ListControl,然后右键-属性,view-Report

MFC listcontrol 分列 添加行数据 点击列头排序

让你的ListControl变成这幅模样!

MFC listcontrol 分列 添加行数据 点击列头排序

2.添加ListControl控件的control类型变量(如:List,下文中要用到)

3.分列并添加点击选中一行的属性()

    List.DeleteAllItems();//先清空

    //set the list's titles
TCHAR rgtsz[][] = { _T("学号"), _T("姓名"),_T("性别"), _T("程序设计得分"), _T("高等数学得分")};
LV_COLUMN lvcolumn;
CRect rect;
List.GetWindowRect(&rect);//获取list的宽度
for (int i = ; i<; 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() / ;//设定列头的宽度
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 = ;
POSITION pos = List.GetFirstSelectedItemPosition();
if (pos == NULL) return; CString temp; // 选择语言的名称字符串
NMLISTVIEW *listItem = (NMLISTVIEW*)pNMHDR; if (- != listItem->iItem) // 如果iItem不是-1,就说明有列表项被选择
{
temp = List.GetItemText(listItem->iItem, );//取出选中行里的列数据,这里取的是第三列,第一列从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 = ; }

8.添加list行数据

List.InsertItem(j, temp);//j为行数,temp为CString
  List.SetItemText(j, , 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()
, studentName(_T(""))
, studentCppScore()
, studentMathScore()
, 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, );
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[][] = { _T("学号"), _T("姓名"),_T("性别"), _T("程序设计得分"), _T("高等数学得分")};
LV_COLUMN lvcolumn;
CRect rect;
//获取列表的宽高
showStudentList.GetWindowRect(&rect);
for (int i = ; i<; 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() / ; //向列表写入配置好的这一列
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()), ); // 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + ) / ;
int y = (rect.Height() - cyIcon + ) / ; // 绘制图标
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 = ;
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, , temp); showStudentList.SetItemText(j, , it->name); if(it->isMale) showStudentList.SetItemText(j, , "男");
else showStudentList.SetItemText(j, , "女"); temp.Format("%lf", it->cppScore);
showStudentList.SetItemText(j, ,temp); temp.Format("%lf", it->mathScore);
showStudentList.SetItemText(j, , temp);
}
showStudentList.SetRedraw(TRUE);
} int CStudentManagementDlg::isValidInput()
{
if (studentCppScore < || studentCppScore > || studentMathScore < || studentMathScore > )
{
AfxMessageBox(_T("有效的分数范围为:0 - 100!\n如有疑问,请查看使用说明。"));
return ;
}
if (studentNumberEdit.GetWindowTextLengthA() > )
{
AfxMessageBox(_T("学号位数应小于19位!\n如有疑问,请查看使用说明。"));
return ;
}
if (studentNameEdit.GetWindowTextLengthA() == )
{
AfxMessageBox(_T("请输入姓名!"));
return ;
}
if (studentCppScoreEdit.GetWindowTextLengthA() == || studentMathScoreEdit.GetWindowTextLengthA() == )
{
AfxMessageBox(_T("请输入分数!"));
return ;
}
if (studentNumberEdit.GetWindowTextLengthA() == )
{
AfxMessageBox(_T("请输入学号!"));
return ;
}
return ;
} void CStudentManagementDlg::addStudent()
{
UpdateData(TRUE);
if (isValidInput() > ) 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() > ) return;
if (manage.change(studentName, studentNumber, studentCppScore, studentMathScore, isMale)) AfxMessageBox(_T("修改失败"));
refreshList();
} void CStudentManagementDlg::deleteStudent()
{
UpdateData(TRUE); //判定编辑框里的内容是否为空。studentNumberEdit为编辑框的control类型的变量
if (studentNumberEdit.GetWindowTextLengthA() == )
{
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 = ; //获取点击的行的位置,showStudentList为列表的control类型变量
POSITION pos = showStudentList.GetFirstSelectedItemPosition();
if (pos == NULL) return; CString temp;
NMLISTVIEW *listItem = (NMLISTVIEW*)pNMHDR; if (- != listItem->iItem) // 如果iItem不是-1,就说明有列表项被选择
{
//GetItemText(点击的行数, 该行的列数)获取对应列的内容
temp = showStudentList.GetItemText(listItem->iItem, );
if (!temp.Compare("男")) isMale = TRUE;
else isMale = FALSE; UpdateData(FALSE); // 获取被选择列表项第一个子项的文本
temp = showStudentList.GetItemText(listItem->iItem, );
// 将选择的语言显示与编辑框中
SetDlgItemText(IDC_EDIT1, temp); temp = showStudentList.GetItemText(listItem->iItem, );
SetDlgItemText(IDC_EDIT2, temp); temp = showStudentList.GetItemText(listItem->iItem, );
SetDlgItemText(IDC_EDIT3, temp); temp = showStudentList.GetItemText(listItem->iItem, );
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 == || manage.sortColumn == || manage.sortColumn == )) return; if (manage.sortColumn == || manage.sortColumn == || manage.sortColumn == ) manage.sortData(manage.sortColumn); *pResult = ; refreshList(); CString msg;
msg.Format("%s",manage.sortColumn == ? "列表内容已根据学号成绩排列! (由小到大的顺序)" : (manage.sortColumn == ? "列表内容已根据程序设计成绩排列! (由高到低的顺序)" : "列表内容已根据高等数学成绩排列! (由高到低的顺序)"));
AfxMessageBox(msg);
} void CAboutDlg::OnStnClickedMainframe()
{
// TODO: 在此添加控件通知处理程序代码
} void CStudentManagementDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
HelpDlg help;
help.DoModal(); } void CStudentManagementDlg::OnGetMinMaxInfo(MINMAXINFO *lpMMI)
{
CPoint pt(, ); //定义宽和高
lpMMI->ptMinTrackSize = pt; //限制最小宽和高
CDialog::OnGetMinMaxInfo(lpMMI);
} void CStudentManagementDlg::OnLvnItemchangedList2(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = ;
}