目录
一、List Control列表控件属性
1.List Control
2.View属性
二、OnInitDialog初始化列表
1.创建List Control的变量
2.找OnInitDialog
3. InsertColumn插入表头
4. InsertColumn设置对齐方式和列宽
5. 设置List的正文内容
6.循环结构创建列表
7.设置列表整行选中和网格
三、结语
目标长这样
一、List Control列表控件属性
1.List Control
在工具箱中找到列表控件,记住,不是List Box,把List Control左键拖入界面中
初始样子是这样的
2.View属性
我们需要把它拉长,拉宽并且,修改View属性
默认View是icon(图标),我们大多时候需要用到的是报表Report
报表选项下,就有了一个类似于表头的(颜色)
虽然编辑界面看上去List Control画画绿绿的,实际上运行起来,啥也没有
二、OnInitDialog初始化列表
1.创建List Control的变量
作用域改为私有private,名称设置为m_list,完成(这个也只能选控件这一类别)
2.找OnInitDialog
在类视图中选中当前我们需要操作的对话框名字带后缀Dlg的文件,双击OnInitDialog,即可跳转到初始化代码块
在return TRUE 适当位置添加初始化代码
3. InsertColumn插入表头
// TODO: 在此添加额外的初始化代码
//列表控件使用
CString str[] = { TEXT("姓名"),TEXT("性别"),TEXT("学号")) };//创建数组,待会儿作为表头
//设置表头
for (int i = 0; i < 3; i++)//三个数组元素,依次插入表列内
{
m_list.InsertColumn(i, str[i]);//依次插入列
}
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
先创建好数组,再在循环内依次在表头对应位置,放置对应元素
InsertColumn,insert是插入的英文,Column是列的英文
运行结果(除了三条竖线,啥也没有)出错了?
别着急,依次向右拉宽三条竖线试试(其实原因就像表格的列宽不够显示文字一样的,后面我们会写到如何设置列宽)
4. InsertColumn设置对齐方式和列宽
查找MFC类的中文手册(帮助文档)时,不知道InsertColumn这个API属于哪个类的成员函数,可以回到界面编辑框右键List Control控件,点击类向导,查看成员变量所属的类型是(CListCtrl),所以在帮助文档中检索InsertColumn的用法时,可以加上作用域CListCtrl::InsertColumn
检索到它的参数有,索引值,地址,字符串地址,对齐方式,列宽等
我们需要的只有 索引值,字符串地址,对齐方式,列宽(int类型)
具体用法如下代码及注释
for (int i = 0; i < 3; i++)//三个数组元素,依次插入表列内
{
//m_list.InsertColumn(i, str[i]);//依次插入列
//设置对齐方式和列宽
m_list.InsertColumn(i, str[i], LVCFMT_LEFT, 180);//LVCFMT_LEFT 左对齐,宽度 100
}
LVCFMT_LEFT是左对齐(第三个参数)
180是列宽(第四个参数)可根据自己的需要调整
运行效果如下
5. 设置List的正文内容
我们还是从行列来看,刚刚的表头不算入内容,内容从0开始
//设置正文,表头不算正文内容,索引从0开始
//插入一个Item行
m_list.InsertItem(0, TEXT("张三"));//第一行的第一个元素是张三
//插入同一行的第二列元素
m_list.SetItemText(0, 1, TEXT("男"));//第一行的第二列性别
//插入同一行的第三列元素
m_list.SetItemText(0, 2, TEXT("2022730001"));//第一行的第三列学号
运行效果如下,按理说,我们不断重复插入行,填入每行的第n列元素就可以完成信息录入,制成完整表格,但是代码就是用来减少工作量的,如果要做一个一百行的表岂不是要有3*100=300行这样的代码么,非常冗杂且不简洁,所以得用for循环来解决
6.循环结构创建列表
我们大概输入个十行,i=0,i<10从1到10一共10行
for (int i = 0; i <10; i++)
{
//创建姓名列
CString name;
name.Format(TEXT("张三_%d"), i+1);//从张三_1到张三——10
m_list.InsertItem(i+1, name);//插入第i+1行索引位置所在的姓名
}
输出结果
每行姓名对应的性别,也用同样的思路写入,只不过它不需要创建CString类型变量接收sex性别,可在SetItemText指定行列插入性别:男
for (int i = 0; i < 10; i++)
{
m_list.SetItemText(i , 1, TEXT("男"));//第i行,从第0行的第2列开始插入性别
}
运行结果如下
插入学号
for (int i = 0; i < 10; i++)
{
CString num;//创建学号变量
num.Format(TEXT("202273000%d"), i );
m_list.SetItemText(i, 2, num);
}
那写在一个循环里面呢,不分成三个循环
这样更简洁,省时间
for (int i = 0; i < 10; i++)
{
//创建姓名列
CString name;
name.Format(TEXT("张三_%d"), i + 1);//从张三_1到张三——10
m_list.InsertItem(i , name);//插入第i+1行索引位置所在的姓名
//性别
m_list.SetItemText(i, 1, TEXT("男"));//第i行第2列插入性别男
//学号
CString num;
num.Format(TEXT("202273000%d"), i);
m_list.SetItemText(i, 2, num);
}
当然,还有看起来更高端的,就是把创建好的每行的第二个和第三个元素换成变量,利用前置递增++j,前缀++,运行出来的就是从第二行(1)开始,比起直接输入1,2指定列,更加让人觉得你很懂
for (int i = 0; i < 10; i++)
{
//列变量
int j = 0;
//创建姓名列
CString name;
name.Format(TEXT("张三_%d"), i + 1);//从张三_1到张三——10
m_list.InsertItem(i , name);//插入第i+1行索引位置所在的姓名
//性别
m_list.SetItemText(i, ++j, TEXT("男"));//第i行第2列插入性别男
//学号
CString num;
num.Format(TEXT("202273000%d"), i);
m_list.SetItemText(i, ++j, num);
}
运行效果是一样的
7.设置列表整行选中和网格
查看我们上一步操作完成的程序,发现它只能单个元素选中,而且不想excel那样有行列分隔的网格线
添加整行选中和显示网格线之前
添加代码后的效果
//设置列表网格线
//LVS_EX_FULLROWSELECT整行选中
//LVS_EX_GRIDLINES显示网格线
m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
三、结语
学习MFC编程的过程中,最痛苦的应该就是像MatLab那样要记忆很多API(MATLAB里面的函数)传什么参数,什么类型的参数,老长串的洋红色字符串,以及有没有返回值,返回值又是什么类型的,但是当初创造出他们的大佬们在给每个API命名的时候呢又是根据它的作用给它用以相应的英文名命名的,所以,看得多了也就没那么可怕了
你以为那些API和用法要全部记下?NO!!!需要用到什么API大概翻译一下它的英文意思,再查看类向导,看它属于哪个类,要用什么查什么,当然背下来更好,会节省很多时间