当前位置: 首页 > article >正文

优化 MFC CGridCtrl 的表格布局与功能

在使用 MFC 的 CGridCtrl 控件创建表格时,遇到的一个典型问题是,当表格滚动条出现时,最后一列会显示空白。这篇博客将记录解决这一问题的详细过程,同时总结了 CGridCtrl 初始化及优化的关键步骤,帮助开发者快速搭建一个功能完善的用户管理表格。


问题描述

在开发用户管理模块时,使用了 MFC 的 CGridCtrl 控件,遇到以下问题:

  1. 当添加的数据超过表格的可视范围,出现垂直滚动条后,表格的最后一列显示空白。
  2. 如果调整某列的宽度,最后一列的内容又可以正常显示。
  3. 通过分析,发现滚动条的宽度未正确考虑到表格的列宽调整逻辑中,导致最后一列被“覆盖”。

解决方法

方法 1:手动调整最后一列宽度

通过监听滚动条的显示状态,在需要时动态调整最后一列的宽度,确保内容可见。或者在添加删除函数中使用调整列宽和填充最后一列。

void CUserManagerDlg::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);
    if (m_gridUserManager.GetSafeHwnd()) {
        m_gridUserManager.ExpandColumnsToFit(FALSE); // 调整列宽
        m_gridUserManager.ExpandLastColumn();        // 填充最后一列
    }
}

方法 2:限制列总宽度

将所有列的总宽度限制为表格的客户区宽度减去滚动条宽度。这种方法更加精确,但实现较为复杂。


优化表格初始化的代码

CGridCtrl 的初始化过程中,我们需要设置表格的行列数、样式以及默认单元格的背景色、字体颜色等属性。以下是经过优化后的初始化代码:

void CUserManagerDlg::InitUserManager()
{
    if (m_gridUserManager.GetSafeHwnd() == NULL)
        return;

    // 清空表格数据
    m_gridUserManager.DeleteAllItems();
    m_gridUserManager.SetVirtualMode(FALSE); // 设置为非虚拟模式

    // 配置默认单元格样式
    m_gridUserManager.GetDefaultCell(TRUE, FALSE)->SetBackClr(g_nGridFixCellColor); // 固定行背景色
    m_gridUserManager.GetDefaultCell(FALSE, TRUE)->SetBackClr(g_nGridFixCellColor); // 固定列背景色
    m_gridUserManager.GetDefaultCell(FALSE, FALSE)->SetBackClr(g_nGridCellColor);   // 普通单元格背景色

    m_gridUserManager.SetFixedTextColor(g_nGridFixFontColor); // 固定行/列字体颜色

    // 设置表格行列数
    int nRows = 1; // 初始只有标题行
    int nCols = 7; // 包含固定列的总列数
    m_gridUserManager.SetRowCount(nRows);
    m_gridUserManager.SetColumnCount(nCols);
    m_gridUserManager.SetFixedRowCount(1);
    m_gridUserManager.SetFixedColumnCount(0);

    // 配置表头
    int nColIdx = 0;
    m_gridUserManager.SetColumnWidth(nColIdx, 30); // 列宽
    m_gridUserManager.SetItemText(0, nColIdx++, _T("No."));
    m_gridUserManager.SetColumnWidth(nColIdx, 70);
    m_gridUserManager.SetItemText(0, nColIdx++, _T("用户名"));
    m_gridUserManager.SetColumnWidth(nColIdx, 70);
    m_gridUserManager.SetItemText(0, nColIdx++, _T("密码"));
    m_gridUserManager.SetColumnWidth(nColIdx, 70);
    m_gridUserManager.SetItemText(0, nColIdx++, _T("权限"));
    m_gridUserManager.SetColumnWidth(nColIdx, 70);
    m_gridUserManager.SetItemText(0, nColIdx++, _T("会话超时(分钟)"));
    m_gridUserManager.SetColumnWidth(nColIdx, 70);
    m_gridUserManager.SetItemText(0, nColIdx++, _T("会话过期(小时)"));
    m_gridUserManager.SetColumnWidth(nColIdx, 100);
    m_gridUserManager.SetItemText(0, nColIdx++, _T("最后一次登录时间"));

    // 配置交互属性
    m_gridUserManager.SetEditable(TRUE);
    m_gridUserManager.SetRowResize(FALSE);
    m_gridUserManager.SetColumnResize(TRUE);
    m_gridUserManager.SetFixedRowSelection(FALSE);
    m_gridUserManager.SetFixedColumnSelection(FALSE);
    m_gridUserManager.SetListMode(TRUE);
    m_gridUserManager.SetSingleRowSelection(TRUE);

    // 自动调整列宽
    m_gridUserManager.ExpandColumnsToFit(TRUE);
    m_gridUserManager.ExpandLastColumn();

    // 填充表格数据
    FillUserManager();
}

初始化中的关键点

  1. 清空表格数据
    使用 DeleteAllItems() 确保表格在初始化前处于空状态。

  2. 设置默认样式
    使用 GetDefaultCell() 设置单元格背景色、字体等全局样式,减少逐个单元格设置的重复工作。

  3. 列宽自动调整
    调用 ExpandColumnsToFit()ExpandLastColumn() 确保列宽自适应表格宽度,避免多余的滚动条。

  4. 交互属性

    • 禁用行高调整:SetRowResize(FALSE)
    • 启用列宽调整:SetColumnResize(TRUE)
    • 只允许选择单行:SetSingleRowSelection(TRUE)

总结

在开发过程中,通过方法 1 手动调整最后一列宽度,成功解决了最后一列显示空白的问题。同时,通过优化 CGridCtrl 的初始化代码,表格的功能更加完善,交互体验也得到了提升。希望这篇文章能为 MFC 开发者提供参考。


http://www.kler.cn/a/401493.html

相关文章:

  • Android开发实战班 - Activity 生命周期
  • 联通光猫(烽火通信设备)改桥接教程
  • 向量数据库FAISS之五:原理(LSH、PQ、HNSW、IVF)
  • 散户持股增厚工具:智能T0算法交易
  • 数据库基本概念学习笔记
  • Datawhale组队学习】模型减肥秘籍:模型压缩技术3——模型量化
  • C语言练习.switch
  • 竞赛思享会 | 2024年第十届数维杯国际数学建模挑战赛D题【代码+演示】
  • 使用OpenFeign+Eureka实现HTTP调用的简单示例
  • 安全平行切面的概念以及对安全行业影响
  • 前端记录3
  • 静态成员的详细讲解
  • Spark RDD 的 combineByKey、cogroup 和 compute 算子的作用
  • 第8章硬件维护-8.2 可维护性和可靠性验收
  • 抽象java入门1.5.3.2——类的进阶(中)
  • 嵌入式C语言
  • 填写工单流程
  • CTF练习4
  • TDSQL 免密码登录
  • Openstack15--块存储服务(Cinder)安装
  • SpringCloud详解
  • 阿里云SSL证书每三个月过期续期方法 —— 使用httpsok工具轻松自动续期
  • 机器学习笔记 // 天气预报、股票价格以及历史轨迹(如摩尔定律)// 时间序列的常见属性
  • 如何在Linux系统实现屏幕旋转?触觉智能RK3568鸿蒙开发板演示
  • JavaSE(十四)——文件操作和IO
  • Jmeter数据库压测之达梦数据库的配置方法