CGridListCtrlEx - 基于CListCtrl的网格控制
2017-06-19 08:43
211 查看
翻译来源:https://www.codeproject.com/Articles/29064/CGridListCtrlEx-Grid-Control-Based-on-CListCtrl
作者:Rolf
Kristensen
目前找到最好的list控件类,还一直在更新
自定义绘制CListCtrl,具有子项目编辑和格式化
下载演示
- 1.6 MB
下载源代码
- 180 KB
排序
单元导航和键盘搜索
提示
隐藏并显示列
单元格编辑
超链接
自定义行和单元格着色
分组
剪贴板(仅复制)
保持列宽,位置和可见性
OLE拖放(包括项目的重新排序)
本文演示如何使用
XP / Vista外观。
在GitHub的-
CGridListCtrlEx可如果想的Git / Subversion的接入使用,并且也有Doxygen文档。
XP和Vista。找到一个很好的替代这个控制不是很容易:
MFC
Grid Control - 不会继承,
终极网格 -
像MFC网格控件,它不会继承
CQuickList -
非常接近于一个完美的替代品,但很难添加新的方式来显示数据,这要求
XListCtrl -
也是一个非常完整
另一个报表列表控制 -
简单易用,但缺少其他方式来编辑除了使用之外的数据,也缺少
CListCtrlEx -
实现了很多功能,并且有很好的记录。最初需要
所述
建议我们不
隐藏 复制代码
当编辑了一个项目时,
隐藏 复制代码
我们可以指定
如果要获取所选项目的
使用数字比较配置列特征进行排序:
隐藏 复制代码
列特征
我们还可以选择覆盖该
隐藏 复制代码
连接图像后,可以在单元格/子项目中绑定索引
该
当使用子项映像并在Windows XP上运行应用程序或使用经典样式时,当选择行时,它将显示白色背景。这可以通过使用
隐藏 复制代码
隐藏 复制代码
记住不要使用
如果要对多个列进行复选框,则可以使用
隐藏 复制代码
分配
在
隐藏 复制代码
也可以
超链接也可用于模拟按钮。当点击它会发送一个
分配
更改网格控件的字体,行高将跟随。
使用
如果使用
Vista上运行。
隐藏 复制代码
如果在应用程序中使用
要实现自己的特殊行为来执行放置操作,可以覆盖
要控制在拖动启动时放置在拖动源中的内容,请覆盖
插入列时,我们可以为列分配一个
在
当继承时
如果执行自定义绘图,我们还必须处理选择和聚焦着色。
如果执行编辑,我们必须确保编辑器在失去焦点时关闭,并
专业化
指定列特征的接口
实现单元格格式化
通过切换图像来实现细胞编辑(可以模拟复选框)
实现细胞编辑
实现细胞编辑
实现细胞编辑
实现细胞行为超链接
指定行特征的界面
实现行格式化
使用经典或XP风格时,执行子图像背景图
持久化列设计的抽象界面
实现接口,并可以在多个列设置之间切换。
支持进度条 - 需要一个
实现
- 具有Windows Vista样式项目选择的WTL列表控件。
对本项目的贡献非常受欢迎。
作者:Rolf
Kristensen
目前找到最好的list控件类,还一直在更新
自定义绘制CListCtrl,具有子项目编辑和格式化
下载演示
- 1.6 MB
下载源代码
- 180 KB
介绍
MicrosoftCListCtrl支持使用报告样式在网格中显示数据,但是我们必须进行几项更改才能实现以下功能:
排序
单元导航和键盘搜索
提示
隐藏并显示列
单元格编辑
超链接
自定义行和单元格着色
分组
剪贴板(仅复制)
保持列宽,位置和可见性
OLE拖放(包括项目的重新排序)
本文演示如何使用
CGridListCtrlEx,它实现了所有上述功能,同时维护Windows
XP / Vista外观。
在GitHub的-
CGridListCtrlEx可如果想的Git / Subversion的接入使用,并且也有Doxygen文档。
背景
有很多高级网格控件可以扩展CListCtrl,其中之一是增强列表控件(CGfxListCtrl)。这个美妙的控件提供了上述所有功能,但无法处理Windows
XP和Vista。找到一个很好的替代这个控制不是很容易:
MFC
Grid Control - 不会继承,
CListCtrl所以它不受它的限制,但它不会受益于Microsoft添加到的任何改进
CListCtrl。
终极网格 -
像MFC网格控件,它不会继承
CListCtrl。最初一个人买的,但现在可以自由使用。
CQuickList -
非常接近于一个完美的替代品,但很难添加新的方式来显示数据,这要求
LVS_OWNERDATA使排序更难。
XListCtrl -
也是一个非常完整
CListCtrl,但很难添加新的方式来显示数据,并且它无法支持
LVS_OWNERDATA。现在必须购买许可证才能获得最新版本。
另一个报表列表控制 -
简单易用,但缺少其他方式来编辑除了使用之外的数据,也缺少
CEdit子导航。
CListCtrlEx -
实现了很多功能,并且有很好的记录。最初需要
LVS_OWNERDRAWFIXED,现在演变成使用自定义画。自定义绘制和所有者绘制的组合导致代码有点复杂,它也不支持
LVS_OWNERDATA。
所述
CGridListCtrlEx插入件称为柱性状一个抽象层处理该细胞绘制和编辑。如果微软
CListCtrl再次扩展,那么希望的核心
CGridListCtrlEx将继续发挥作用。
如何使用CGridListCtrlEx
在CGridListCtrlEx试图留真实的
CListCtrl,并且不试图取代的东西
CListCtrl已经提供。这意味着我们可以替换一个
CListCtrl,
CGridListCtrlEx而不需要再做任何事情。
建议我们不
CGridListCtrlEx直接使用,而是创建一个继承/派生的新类
CGridListCtrlEx。这将使以后更容易将任何更新迁移到
CGridListCtrlEx课程中。
编辑单元格/子项目
默认情况下,当插入列时CGridListCtrlEx,它们将被配置为只读,无需编辑。通过使用
CGridListCtrlEx::InsertColumnTrait(),我们可以提供一个
CGridColumnTrait类,它指定应该使用哪种类型的编辑器。
隐藏 复制代码
CGridColumnTrait* pTrait = new CGridColumnTraitEdit; m_ListCtrl.InsertColumnTrait(nCol, title.c_str(), LVCFMT_LEFT, 100, nCol, pTrait);
当编辑了一个项目时,
LVN_ENDLABELEDIT会发送一个标准的消息
CListCtrl。当
CGridListCtrlEx接收到该消息时,它将自动调用虚拟方法
CGridListCtrlEx::OnEditComplete(),允许派生类验证输入,并可能更新底层数据模型。
使用组合框编辑单元格/子项
通过使用CGridListCtrlEx::InsertColumnTrait(),我们也可以提供一个
CGridColumnTrait作为一个工作的类
CComboBox。
隐藏 复制代码
CGridColumnTraitCombo* pTrait = new CGridColumnTraitCombo; pTrait->AddItem(0, "Hello"); pTrait->AddItem(1, "Goodbye"); m_ListCtrl.InsertColumnTrait(nCol, title.c_str(), LVCFMT_LEFT, 100, nCol, pTrait);
我们可以指定
CComboBox插入列时的项目(如上所示)。如果我们要动态提供
CComboBox项目,那么我们可以覆盖
CGridListCtrlEx::OnEditBegin()。使用
dynamic_cast<>要么调用列特征的方法
CGridColumnTraitCombo::LoadList(),或者对返回的工作
CComboBox-editor直接。
如果要获取所选项目的
CComboBoxitemdata,则可以覆盖
CGridListCtrlEx::OnEditComplete()并检查参数值
pLVDI->item.lParam。需要将itemdata保存在其他位置,因为它不能存储在本地数据模型中
CListCtrl。
排序行
默认情况下,GridListCtrlEx将为所有列启用排序,其中它将执行简单的文本比较。通过列特征可以通过覆盖来实现自定义排序
CGridColumnTrait::OnSortRows()。
使用数字比较配置列特征进行排序:
隐藏 复制代码
CGridColumnTraitEdit* pTrait = new CGridColumnTraitEdit; pTrait->SetSortFormatNumber(true); // Numeric column m_ListCtrl.InsertColumnTrait(nCol, title.c_str(), LVCFMT_LEFT, 100, nCol, pTrait);
列特征
CGridColumnTraitDateTime将自动尝试使用日期比较进行排序。
我们还可以选择覆盖该
CGridListCtrlEx::SortColumn()方法。那么这只是一个选择正确的排序方法的问题。另请参见CListCtrl和排序行。
显示工具提示
默认情况下,CGridListCtrlEx将仅将单元格内容显示为工具提示。如果我们想在工具提示中显示不同的东西,那么我们可以覆盖该
CGridListCtrlEx::OnDisplayCellTooltip()方法。
格式化单元格/子项
如果要更改前景/背景颜色或字体样式(粗体,斜体,下划线),则可以覆盖方法CGridListCtrlEx::OnDisplayCellColor()和
CGridListCtrlEx::OnDisplayCellFont()。
隐藏 复制代码
bool MyGridCtrl::OnDisplayCellColor(int nRow, int nCol, COLORREF& textColor, COLORREF& backColor) { if (nRow == 3 && nCol == 3) { textColor = RGB(0,255,0); backColor = RGB(0,0,255); return true; // I want to override the color of this cell } return false; // Use default color }
显示单元格/子图像
在CGridListCtrlEx启用扩展样式
LVS_EX_SUBITEMIMAGES默认,但一个仍然需要附加
CImageList使用
CListCtrl::SetImageList()。
连接图像后,可以在单元格/子项目中绑定索引
CImageList。这可以通过
CGridListCtrlEx::SetCellImage(),或者如果使用
I_IMAGECALLBACK然后通过覆盖返回图像索引
CGridListCtrlEx::OnDisplayCellImage()。
该
CGridListCtrlEx也使得扩展样式
LVS_EX_GRIDLINES默认情况下,这可能会导致子项目图像重叠网格边界。这可以通过确保图像仅使用16像素中的15个(第一像素透明)来解决。
当使用子项映像并在Windows XP上运行应用程序或使用经典样式时,当选择行时,它将显示白色背景。这可以通过使用
CGridRowTraitXP:
隐藏 复制代码
m_ListCtrl.SetDefaultRowTrait(new CGridRowTraitXP);
复选框支持
CListCtrl支持开箱即用的标签列的复选框。只适用扩展风格
LVS_EX_CHECKBOXES:
隐藏 复制代码
m_ListCtrl.SetExtendedStyle(m_ListCtrl.GetExtendedStyle() | LVS_EX_CHECKBOXES);
记住不要使用
InsertHiddenLabelColumn(),因为它会隐藏标签列及其复选框。可以使用
GetCheck()/
SetCheck()检索/修改复选框值。
如果要对多个列进行复选框,则可以使用
CGridColumnTraitImage(及其专业化):
隐藏 复制代码
// Appends the unchecked/checked state images to the list control image list int nStateImageIdx = CGridColumnTraitImage::AppendStateImages(m_ListCtrl, m_ImageList); m_ListCtrl.SetImageList(&m_ImageList, LVSIL_SMALL); // Creates an image column, that can switch between the 2 images CGridColumnTrait* pTrait = new CGridColumnTraitImage(nStateIdx, 2); m_ListCtrl.InsertColumnTrait(nCol, title.c_str(), LVCFMT_LEFT, 20, nCol, pTrait); for(int i=0; i < m_ListCtrl.GetItemCount(); ++i) m_ListCtrl.SetCellImage(i, nCol, nStateImageIdx); // Uncheck item
分配
CImageList使用时,标签列将自动显示图像列
SetImageList()。不可能禁用此行为,但可以隐藏标签列
InsertHiddenLabelColumn()。
CGridColumnTraitImage使用单元格图像绘制复选框,因此不可能在同一列中同时具有单元格图像和复选框。要获取并设置选中/未选中的状态,可以使用
GetCellImage()/
SetCellImage()。
CGridColumnTraitImage支持根据是否启用复选框进行排序。使用
CGridColumnTraitImage::SetSortImageIndex()启用它。
CGridColumnTraitImage还支持切换所有选定行的复选框。使用
CGridColumnTraitImage::SetToggleSelection()启用它。
超链接支持
超链接列可以将单元格内容显示为链接,可以点击链接,并启动外部应用程序,如默认Web浏览器(http)或电子邮件客户端(mailto)。在
CGridColumnTraitHyperLink允许一个提供用于CELLTEXT,它允许一个添加额外的协议的细节没有它正在显示的前缀(和后缀):
隐藏 复制代码
CGridColumnTraitHyperLink* pHyperLinkTrait = new CGridColumnTraitHyperLink; pHyperLinkTrait->SetShellFilePrefix(_T("http://en.wikipedia.org/wiki/UEFA_Euro_")); m_ListCtrl.InsertColumnTrait(nCol, title.c_str(), LVCFMT_LEFT, 100, nCol, pHyperLinkTrait);
也可以
CGridColumnTraitHyperLink::SetShellApplication()指定要启动的自定义应用程序,而不仅仅是基于协议前缀启动的默认应用程序。
超链接也可用于模拟按钮。当点击它会发送一个
LVN_ENDLABELEDIT通知,哪一个可以视为按钮点击通知在父视图中。
更改行高
该CGridListCtrlEx用途customdraw,所以只有这些可用的解决方案:
分配
CImageList图像具有该行所需高度的位置。
更改网格控件的字体,行高将跟随。
CGridListCtrlEx::SetCellMargin()使用这个技巧来增加网格控件的字体,同时保持行字体不变。
更改空标记文本
当CGridListCtrlEx不包含任何项目时,它将显示标记文本以指示列表为空。
使用
CGridListCtrlEx::SetEmptyMarkupText()更改此标记文本。如果提供空文本,那么它的行为就像一个正常的
CListCtrl。
如果使用
CGridListCtrlGroups,它会反应
LVN_GETEMPTYMARKUP如果在Windows
Vista上运行。
加载并保存列宽和位置
CViewConfigSectionWinApp提供存储宽度,位置以及是否显示列的能力。在已经加入所有可用列的
CGridListCtrlEx,分配的一个实例
CViewConfigSectionWinApp使用
CGridListCtrlEx::SetupColumnConfig(),它会通过恢复上次保存的列配置
CWinApp。
隐藏 复制代码
m_ListCtrl.SetupColumnConfig(new CViewConfigSectionWinApp("MyList"));
如果在应用程序中使用
CGridListCtrlEx了几个地方,那么应该确保
CViewConfigSectionWinApp为每个地方创建一个独特的地方。
OLE拖放
CGridListCtrlEx都可以作为OLE拖动源和OLE放置目标。这允许在
CGridListCtrlEx其他窗口和应用程序之间进行拖动操作。
CGridListCtrlEx在执行内部拖放操作时,支持重新排列行。这是使用特殊的排序操作实现的,因此项目不会被删除/插入。
要实现自己的特殊行为来执行放置操作,可以覆盖
OnDropSelf()或
OnDropExternal()根据您想要处理的情况。
要控制在拖动启动时放置在拖动源中的内容,请覆盖
OnDisplayToDragDrop()。
CGridColumnTrait如何工作?
CGridListCtrlEx试图避免所有关于如何显示和编辑数据的令人讨厌的细节。这些事情是由
CGridColumnTrait类来处理的,如果我们要修改数据的显示方式,那么“只是”创建一个新
CGridColumnTrait类就是一个问题。
插入列时,我们可以为列分配一个
CGridColumnTrait。该
CGridListCtrlEx会激活相应的
CGridColumnTrait,当我们需要绘制在列的单元格,或修改此列的单元格。
在
CGridColumnTrait包括被称为元数据的一些特殊成员。这些成员可以由您自己的类使用,当它派生时
CGridListCtrlEx,我们可以轻松地向列添加额外的属性。
当继承时
CGridColumnTrait,我们必须考虑以下几点:
如果执行自定义绘图,我们还必须处理选择和聚焦着色。
如果执行编辑,我们必须确保编辑器在失去焦点时关闭,并
LVN_ENDLABELEDIT在编辑完成时发送消息。
CGridRowTrait如何工作?
它基于相同的想法,CGridColumnTrait但在行级别而不是列级别运行。这对于必须修改所有列的显示行为的情况非常有用。
使用代码
源代码包括以下类:CGridListCtrlEx-
专业化
CListCtrl
CGridListCtrlGroups-
CGridListCtrlEx扩展支持分组
CGridColumnTrait-
指定列特征的接口
CGridColumnTraitText-
实现单元格格式化
CGridColumnTraitImage-
通过切换图像来实现细胞编辑(可以模拟复选框)
CGridColumnTraitEdit-
实现细胞编辑
CEdit
CGridColumnTraitCombo-
实现细胞编辑
CComboBox
CGridColumnTraitDateTime-
实现细胞编辑
CDateTimeCtrl
CGridColumnTraitHyperLink-
实现细胞行为超链接
CGridRowTrait-
指定行特征的界面
CGridRowTraitText-
实现行格式化
CGridRowTraitXP-
使用经典或XP风格时,执行子图像背景图
CViewConfigSection-
持久化列设计的抽象界面
CViewConfigSectionWinApp-
实现接口,并可以在多个列设置之间切换。
要做的事
在CGridListCtrlEx尝试执行任何图纸本身望而却步。这意味着以下功能/错误将不会受到很多关注:
支持进度条 - 需要一个
CGridColumnTrait绘制整个单元格的类。
实现
CGridColumnTrait绘制整个单元格的类可能可以通过从ListCtrl中窃取/借用一些代码来完成
- 具有Windows Vista样式项目选择的WTL列表控件。
对本项目的贡献非常受欢迎。
相关文章推荐
- GridGIS——基于网格计算的地理信息系统
- 基于平均法线实现顶点网格变形控制的总结
- 基于平均法线实现顶点网格变形控制的总结
- 基于平均法线实现顶点网格变形控制的总结
- 基于网格技术的计算能力提供—对GridASP有效业务处理进行概念证明实验的开端
- 基于平均法线实现顶点网格变形控制的总结
- 【转载】基于平均法线实现顶点网格变形控制的总结
- Azure 门户中基于角色的访问控制入门
- 基于java过滤器实现web系统的IP访问控制
- 交换网络安全防范系列五之802.1x-基于端口的网络访问控制技术
- httpd-2.4 基于IP和基于用户的访问控制
- 基于Qt Gui的Led控制显示程序
- 如何在基于kafka和ELK stack的日志分析系统中进行流量控制
- 在ASP.NET MVC中实现基于URL的权限控制
- 基于嵌入式smtp远程控制平台文档
- 基于角色管理的系统访问控制(转载)
- STING:统计信息网格(STatistical INformation Grid)
- 基于Express框架的会话控制
- 使用开源Grid平台-GridGain实现网格计算
- 使用Lync 2013 基于角色的权限控制:RBAC 给用户分配指定的操作权限