多列列表视图控件 (SMCListView)¶
SOUI 中的多列列表视图控件,类似于 Windows 的列表控件,支持多列数据显示,具有表头、排序、列宽调整等功能。基于虚拟化(adapter)技术实现,适用于大量数据的表格形式展示。
基本信息¶
- 类名:
SMCListView - 控件标签:
mclistview - 基类:
SPanel(TPanelProxy<IMcListView>+SViewBase);不是SListView的子类 - 功能:提供多列数据表格形式展示
重要纠正:旧文档列出的
gridLines(bool)属性在源码中不存在。SMCListView没有布尔“显示网格线”开关,网格颜色由colorGrid(color)控制;未设置colorGrid时不绘制网格。另外旧文档缺少hotTrack/dividerSkin/dividerSize等真实属性。
属性说明¶
SMCListView::SOUI_ATTRS_BEGIN 中声明的属性,并通过 ATTR_CHAIN_CLASS(SViewBase) 继承选择相关属性:
自身属性¶
| 属性名 | 类型 | 默认值 | 是否重绘 | 说明 |
|---|---|---|---|---|
headerHeight |
layoutsize | 未设置(0) | 否 | 表头高度 |
hotTrack |
int | 0 |
否 | 是否启用热点跟踪(鼠标悬停高亮整行),0=关闭,1=开启 |
dividerSkin |
skin | 无 | 是 | 表头/列之间的分割线皮肤 |
dividerSize |
layoutsize | 未设置(0) | 否 | 分割线尺寸 |
colorGrid |
color | 0(透明) |
是 | 网格线颜色;设为非透明色即绘制网格 |
wantTab |
bool | false |
否 | 是否响应 Tab 键(由 SViewBase 提供) |
multiSel |
bool | false |
否 | 是否允许多选(由 SViewBase 提供) |
说明:列定义(标题、宽度、对齐、排序)通过子节点
<header>配置,属于SHeaderCtrl的属性,不在此表的mclistview自身属性之列。
使用示例¶
mclistview 在 listview 的基础上增加了表头(SHeaderCtrl)。列定义既可在 XML 的 <headerStyle>/<items> 中静态声明,也可用 InsertColumn() 在代码中动态插入;数据同样由 IMcAdapter(便捷基类 SMcAdapterBase)提供。完整可运行示例见 demos/mclistview_demo/StudentSmsDlg.cpp。
1. XML(静态表头 + 分组/数据两种行模板)¶
<mclistview pos="10,10,-10,-10" name="mclist_student"
headerHeight="30" colorGrid="#E0E0E0">
<headerStyle align="center" itemSwapEnable="1" sortHeader="1" itemSkin="sms.header">
<items>
<item width="200">昵称</item>
<item width="215">有效期</item>
<item width="75">忠诚度</item>
</items>
</headerStyle>
<template itemHeight="26">
<item_group colorHover="#e4f0fc" colorSelected="#e4e0ec">
<check name="chk_select_group" pos="0,|0" offset="0,-0.5"/>
<toggle name="tgl_tv_expand" pos="[6,|0" offset="0,-0.5" skin="_skin.sys.tree.toggle"/>
<text name="txt_group" pos="[5,|0" offset="0,-0.5" font="bold:1"/>
</item_group>
<item_data colorHover="#e4f0fc" colorSelected="#e4e0ec">
<text name="txt_nick" pos="24,|0" offset="0,-0.5">sb01</text>
<text name="txt_time_span" pos="10,|0" offset="0,-0.5">2015/9 - 2028/9</text>
<text name="txt_loyal_degree" pos="-15,|0" offset="-1,-0.5">10000</text>
</item_data>
</template>
</mclistview>
列名在 XML 中声明;适配器通过
GetColumnName(iCol)返回每列在模板中对应的窗口名(如col_nick/col_time_span/col_loyal_degree),控件据此把数据填到正确的列。item_group/item_data两种模板演示“分组头 + 可折叠数据行”。
2. 实现适配器(C++)¶
#include <helper/SAdapterBase.h>
#include <control/SMCListView.h>
struct Stu
{
SStringT strNick;
UINT imid;
BOOL bChecked;
};
class CStudentAdapter : public SMcAdapterBase
{
public:
void AddStudent(const Stu &s)
{
m_stu.Add(s);
notifyDataSetChanged();
}
protected:
virtual int WINAPI getCount() override { return m_stu.GetCount(); }
virtual int WINAPI getItemViewType(int position) override
{
return (position == 0) ? 0 : 1;
}
virtual int WINAPI getViewTypeCount() override { return 2; }
virtual SStringW WINAPI GetColumnName(int iCol) const override
{
SStringW cols[] = {L"col_nick", L"col_time_span", L"col_loyal_degree"};
return cols[iCol];
}
virtual void WINAPI getView(int position, SItemPanel *pItem, SXmlNode xmlTemplate) override
{
int vt = getItemViewType(position);
if (pItem->GetChildrenCount() == 0)
{
SXmlNode sub = (vt == 0) ? xmlTemplate.child(L"item_group")
: xmlTemplate.child(L"item_data");
pItem->InitFromXml(&sub);
}
if (vt == 1)
{
const Stu &s = m_stu[position - 1];
pItem->FindChildByName2<SStatic>(L"txt_nick")
->SetWindowText(SStringT().Format(_T("%s(%u)"), s.strNick, s.imid));
}
}
private:
SArray<Stu> m_stu;
};
3. 绑定与动态插列¶
void InitMcList(SMCListView *pList)
{
CStudentAdapter *pAdapter = new CStudentAdapter;
pAdapter->AddStudent({_T("张三"), 1001, FALSE});
pAdapter->AddStudent({_T("李四"), 1002, FALSE});
pList->SetAdapter(pAdapter);
pAdapter->Release();
// 也可在代码里动态插列(会覆盖 XML 静态表头):
// pList->InsertColumn(0, L"昵称", 200, LVCFMT_LEFT);
// pList->InsertColumn(1, L"有效期", 215, LVCFMT_LEFT);
// pList->InsertColumn(2, L"忠诚度", 75, LVCFMT_RIGHT);
pList->SetMultiSel(TRUE);
}