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

 

  

posted @ 2016-01-08 09:17  Ficow  阅读(2147)  评论(0编辑  收藏  举报