Delphi开发:如何让TRzCheckList仅显示名称存储Name=Value键值对?
TRzCheckList实现隐藏关联Value、仅展示名称的操作方法
问题根因
TRzCheckList所属的Items集合底层继承自标准TStringList,本身没有内置“展示名/存储值”分离的渲染机制:
- 调用
Items.ValueFromIndex赋值、Items.AddPair方法写入键值时,底层会自动将Name=Value格式拼接成完整字符串,直接作为项的可视文本渲染在控件区域 - 控件默认不会主动切割拼接后的字符串、隐藏Value部分,因此会出现拼接内容全量直接展示的现象。
可落地实现方案
方案1:通过Objects属性挂载隐藏值(推荐)
这是VCL列表类控件通用的键值对实现方式,不需要修改控件原生绘制逻辑,性能和稳定性最优:
- 添加项时,直接传入需要展示的纯文本Name作为项的可视内容,不要拼接Value
- 将关联的隐藏Value值,通过项索引挂载到对应
Items.Objects槽位上
示例代码:
var ItemIndex: Integer; HideValue: string; begin HideValue := 'MyValue'; // 添加仅展示'MyName'的列表项到指定分组 ItemIndex := RzCheckList1.AddItemToGroup(0, 'MyName'); // 将隐藏值挂到当前项的Objects属性上 RzCheckList1.Items.Objects[ItemIndex] := TObject(HideValue); end;
后续读取指定项的隐藏值时,直接通过索引强转获取即可:
// 获取指定索引项的隐藏关联值 function GetItemHideValue(Index: Integer): string; begin Result := string(RzCheckList1.Items.Objects[Index]); end;
注意:挂载的字符串对象需要保证生命周期覆盖控件的使用周期,不要直接引用栈上临时变量的字符串,避免内存访问异常。
方案2:自定义绘制逻辑拆分显示文本
如果需要保留AddPair的键值存储形式,可以通过控件自绘模式实现展示拆分:
- 将RzCheckList的
Style属性设置为bsOwnerDraw,开启自绘权限 - 在
OnDrawItem事件中,读取项存储的完整Name=Value内容,仅截取等号前的Name部分绘制到控件画布上
示例事件代码:
procedure TForm1.RzCheckList1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var FullText, DisplayText: string; EqualSignPos: Integer; begin // 填充项背景 RzCheckList1.Canvas.FillRect(Rect); // 读取项存储的完整键值文本 FullText := RzCheckList1.Items[Index]; // 定位等号位置,截取展示用的Name部分 EqualSignPos := Pos('=', FullText); if EqualSignPos > 0 then DisplayText := Copy(FullText, 1, EqualSignPos - 1) else DisplayText := FullText; // 绘制勾选框预留位置后的展示文本 RzCheckList1.Canvas.TextOut(Rect.Left + 20, Rect.Top + 3, DisplayText); end;
避坑说明
TStringList的ValueFromIndex、AddPair方法本质是为了方便解析键值对设计的,本身没有“存储值隐藏不显示”的逻辑,直接赋值必然会同步修改项的可视文本- 不要通过修改分隔符之类的属性试图改变默认显示行为,这类配置只影响字符串解析逻辑,不影响控件的文本渲染规则。
内容的提问来源于stack exchange,提问作者user1580348
相关产品推荐
相关产品推荐

