您的位置:首页 > 其它

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

2016-01-08 09:17 316 查看
适用于 对话框程序

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;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: