MFC属性网格去除多余部分

静态创建了一个属性网格CMFCPropertyGridCtrl,怎么把下方图片红线所示区域去除啊?

img

以下答案由GPT-4.5Plus大模型(语音)与博主A努力中.......共同编写:

在MFC属性网格中去除多余的空白部分,可以采取以下几种方法:

  1. 调整列宽
    可以适当缩窄属性网格的列宽,使之刚好适配属性内容,这样可以避免出现空列。设置列宽的方法是:
cpp
m_wndPropGrid.SetColumnWidth(nColumn, nWidth); 

  1. 隐藏空白列
    通过判断属性网格中的每一列是否为空,如果为空则隐藏这一列。代码如下:
cpp 
for (int i = 0; i < m_wndPropGrid.GetColumnCount(); i++)
{
    CString strCellText = m_wndPropGrid.GetItemText(0, i);
    if (strCellText.IsEmpty())
    {
        m_wndPropGrid.ShowColumn(i, FALSE);
    }
}

  1. 调整行高
    如果属性网格中最后几行为空,可以设置这几行的行高为0,隐藏空白行。代码如下:
cpp
for (int i = m_wndPropGrid.GetRowCount() - 1; i >= 0; i--) 
{
    CString strItemText = m_wndPropGrid.GetItemText(i, 0);
    if (strItemText.IsEmpty())
    {
        m_wndPropGrid.SetRowHeight(i, 0);
    }
    else
    {
        break;
    }
}

  1. 隐藏空白单元格
    通过遍历属性网格中的每一个单元格,如果单元格为空则隐藏此单元格。代码如下:
cpp
for (int row = 0; row < m_wndPropGrid.GetRowCount(); row++)
{
    for (int col = 0; col < m_wndPropGrid.GetColumnCount(); col++) 
    {
        CString strItemText = m_wndPropGrid.GetItemText(row, col);
        if (strItemText.IsEmpty())
        {
            m_wndPropGrid.SetItemState(row, col, 0,rgb);
        }
    }
}

以上4种方法可以有效去除MFC属性网格中的空白部分,使界面的显示更加紧凑。

您可以使用EnableHeaderCtrl()函数来隐藏属性网格中的头部控件。

具体实现方式如下:

cpp
CMFCPropertyGridCtrl m_PropGrid; // 用于代表您所创建的属性网格

// 当您在 OnInitDialog() 函数中进行初始化时,添加以下代码:
m_PropGrid.EnableHeaderCtrl(FALSE);
注意,这个函数必须在创建控件之后才能调用。如果在 OnCreate() 或其他地方设置 EnableHeaderCtrl() 则会返回错误。

通过上述修改,您应该就能够成功去除属性网格底部的标头控制了。

可以借鉴下

    BOOL CPropertySysDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    // TODO: 在此添加额外的初始化代码
    m_propertyGridCtrl.EnableHeaderCtrl(FALSE);
    m_propertyGridCtrl.SetVSDotNetLook(FALSE);//描述是否按照.NET的样式绘制控件
    m_propertyGridCtrl.MarkModifiedProperties(TRUE);//指定如何显示修改后的属性
    m_propertyGridCtrl.SetAlphabeticMode(FALSE);//设置或重置字母模式
    m_propertyGridCtrl.EnableDescriptionArea(TRUE);//启用或禁用在属性列表下方显示的说明区域
    m_propertyGridCtrl.SetDescriptionRows(3);//设置描述区域的行数
    m_propertyGridCtrl.SetShowDragContext();//指定当用户调整列的大小时,框架是否重绘当前属性网格控件的名称和值列
    //设置表头宽度
    HDITEM item;
    item.cxy = 120;
    item.mask = HDI_WIDTH;
    m_propertyGridCtrl.GetHeaderCtrl().SetItem(0, new HDITEM(item));
    //new出来的pGroup和subitem项,不需要手动释放,由m_propertyGridCtrl释放即可
    CMFCPropertyGridProperty* pGroup = new CMFCPropertyGridProperty(_T("灯具属性"));
    CMFCPropertyGridProperty* pNameItem = new CMFCPropertyGridProperty(_T("名称"), _T("白炽灯"), _T("灯具名称"));
    pNameItem->AllowEdit(FALSE);//不允许编辑
    pGroup->AddSubItem(pNameItem);
    CMFCPropertyGridProperty* pPowerItem = new CMFCPropertyGridProperty(_T("功率(W)"), _T("100"), _T("灯具功率"));
    pPowerItem->AllowEdit(TRUE);
    pGroup->AddSubItem(pPowerItem);
    CMFCPropertyGridProperty* pPriceItem = new CMFCPropertyGridProperty(_T("价格(人民币)"), _T("8.2"), _T("灯具价格"));
    pPriceItem->AddOption(_T("8.2"));
    pPriceItem->AddOption(_T("10.25"));
    pPriceItem->AddOption(_T("12.00"));
    pPriceItem->AllowEdit(TRUE);
    pGroup->AddSubItem(pPriceItem);
    //添加一个属性
    m_propertyGridCtrl.AddProperty(pGroup);
    m_propertyGridCtrl.ExpandAll(TRUE);

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}


两个方法,看一看

1.手动删除
1.首先确定控件有哪些相关的变量和函数;打开.rc2文件在里面删除对应的控件图标;

2.打开主对话框头文件;(一般类向导生成的函数和变量定义都在头文件的最后一个“public”l里);找到生成的变量定义和函数定义将其删除;

3.打开对话框源文件,找到控件定义的处理函数,将其删除(也可在最开始时双击控件按钮找到定义函数进行删除)

4.在BEGIN_MESSAGE_MAP()消息映射函数里,将控件对应的消息函数删除(一般有有波浪线标志)

5.最后删除变量的数据交换语句;在void CTestDlg::DoDataExchange(CDataExchange* pDX)函数里;这里的test为自定义的函数。

2.通过类向导删除
1.打开.rc文件;找到欲删除的控件;选中控件后按右键;选择“类向导”;在类向导页面找到控件对应的消息、成员变量,选中后点击“删除处理程序”;有的控件没有事件函数,可以直接删除,比如文本

此时在源文件里变量的定义声明、数据交换函数的相关语句、消息映射中的信息都被注释了。

2.在对话框内删除控件。