• 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!
    如有疑问,请查看使用说明。"));
            return 1;
        }
        if (studentNumberEdit.GetWindowTextLengthA() > 18)
        {
            AfxMessageBox(_T("学号位数应小于19位!
    如有疑问,请查看使用说明。"));
            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;
    }

      

  • 相关阅读:
    TP5.1 路由验证器验证返回json提示
    win10 docker ubuntu14.04 php 编译安装 php7.3.20
    ubuntu15.10 sources.list 修改
    秒杀系统设计
    class命名规范
    php实现阿里云签名类
    【小程序】应用的生命周期,页面的生命周期
    php.ini配置文件参数中文说明文档
    tp5.1 nginx配置
    phpstudycomposer thinkPHP5.1 使用
  • 原文地址:https://www.cnblogs.com/ficow/p/5111983.html
Copyright © 2020-2023  润新知