这星河灿烂. 2024-06-05 14:26 采纳率: 15.6%
浏览 1
已结题

MFC中LIST控件得问题

img


如图:在MFC中得一个List列表,我想实现就一行18aedoe4,但是可以吧这一行展开,就是一行有很多子行,怎么实现?

  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-05 14:26
    关注

    引自免费微信小程序:皆我百晓生

    为了实现你描述的需求,你需要创建一个自定义的控件,继承自CListCtrl,然后重写一些必要的消息处理函数,例如OnLVN_BEGINDRAGOnLVN_BEGINRDRAGOnLvnItemexpanded等,以便支持折叠和展开功能。这里是一个简化的步骤指南和部分关键代码片段。

    首先,创建一个新的MFC项目,选择"Empty Project",并确保包含对话框类。

    1. 创建一个新的C++类,比如名为CMyListCtrl,继承自CListCtrl。
    2. 在资源视图中,将列表控件的Class ID改为新创建的类名(CMyListCtrl)。
    3. 在CMyListCtrl类中添加成员变量用于存储折叠状态,并在构造函数中初始化它们。
    4. 重写OnLVN_BEGINDRAGOnLVN_BEGINRDRAGOnLvnItemexpanded等消息处理函数。
    5. 实现折叠/展开逻辑,根据需要动态调整列表项的高度。
    6. 添加右键菜单,提供折叠/展开操作。

    以下是关键代码段:

    class CMyListCtrl : public CListCtrl
    {
    public:
        CMyListCtrl();
        // ...其他声明
    
    protected:
        afx_msg void OnLVN_BEGINDRAG(NMHDR *pNMHDR, LRESULT *pResult);
        afx_msg void OnLVN_BEGINRDRAG(NMHDR *pNMHDR, LRESULT *pResult);
        afx_msg void OnLvnItemexpanded(NMHDR *pNMHDR, LRESULT *pResult);
    
    private:
        std::map<int, bool> m_ItemExpanded; // 存储折叠状态,key是item的索引,value是布尔值表示是否展开
    };
    
    CMyListCtrl::CMyListCtrl()
    {
        m_ItemExpanded.clear(); // 初始化为空
    }
    
    void CMyListCtrl::OnLVN_BEGINDRAG(NMHDR *pNMHDR, LRESULT *pResult)
    {
        NMLISTVIEW* pListView = (NMLISTVIEW*)pNMHDR;
        if (pListView->iItem == -1)
            return;
    
        // 避免拖动时意外触发折叠/展开
        *pResult = 0;
    }
    
    void CMyListCtrl::OnLVN_BEGINRDRAG(NMHDR *pNMHDR, LRESULT *pResult)
    {
        NMLISTVIEW* pListView = (NMLISTVIEW*)pNMHDR;
        if (pListView->iItem == -1)
            return;
    
        // 避免拖动时意外触发折叠/展开
        *pResult = 0;
    }
    
    void CMyListCtrl::OnLvnItemexpanded(NMHDR *pNMHDR, LRESULT *pResult)
    {
        NMLISTVIEW* pListView = (NMLISTVIEW*)pNMHDR;
        int iItem = pListView->iItem;
    
        if (iItem == -1)
            return;
    
        // 根据新的展开状态更新高度
        int nNewHeight;
        if (m_ItemExpanded[iItem])
        {
            // 收缩
            nNewHeight = GetLineHeight(iItem) * 2; // 假设一行默认高度为2,具体根据实际调整
        }
        else
        {
            // 展开
            nNewHeight = GetTotalHeight() - GetLineHeight(iItem); // 获取所有未展开行的高度
        }
    
        SetItemHeight(iItem, nNewHeight);
    
        // 更新其他可见行的位置
        for (int i = iItem + 1; i < GetItemCount(); ++i)
        {
            SetItemPosition(i, i - 1, 0); // 移动一行
        }
    
        m_ItemExpanded[iItem] = !m_ItemExpanded[iItem]; // 反转当前item的展开状态
    
        *pResult = 0;
    }
    

    接下来,你需要在你的对话框类中创建一个CMyListCtrl对象,并为其填充数据。这可以通过使用InsertItem方法完成,同时设置每一行的子行数。当用户点击右键时,显示一个菜单,提供折叠/展开选项。

    注意:以上代码只是一个基本示例,可能需要根据你的具体需求进行修改。如果你需要完整的代码,包括UI设计和事件关联,你可能需要学习更多关于MFC的知识,或者考虑使用更现代的Windows API,如WinRT或WPF。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月6日
  • 创建了问题 6月5日

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见