CheckedListBox 显示中文,后台存英文(显示/值分离)
CheckedListBox的 Item 可以不存字符串,存对象:对象里面一个是给界面显示的中文,一个是程序逻辑用的英文实体名。界面展示中文;你取选中项的时候拿到对象,直接读英文字段,不需要做映射转换。
1. 定义简单实体类
/// <summary> /// CAD实体类型,界面显示中文,程序使用英文 /// </summary> public class EntityTypeItem { /// <summary>界面给用户看的中文</summary> public string DisplayText { get; set; } /// <summary>程序内部使用的CAD英文实体名</summary> public string EntityName { get; set; } // 控制CheckedListBox显示什么文本 public override string ToString() { return DisplayText; } }关键点:重写
ToString(),CheckedListBox 就会拿这个当显示文本,Items 内部存完整对象。
2. 绑定数据
private CheckedListBox _chkEntityTypes; // 初始化,中文显示,底层存英文 var entityList = new List<EntityTypeItem> { new EntityTypeItem{ DisplayText = "插入块(INSERT)", EntityName = "INSERT"}, new EntityTypeItem{ DisplayText = "直线(LINE)", EntityName = "LINE"}, new EntityTypeItem{ DisplayText = "多段线(LWPOLYLINE)", EntityName = "LWPOLYLINE"}, new EntityTypeItem{ DisplayText = "单行文本(TEXT)", EntityName = "TEXT"}, new EntityTypeItem{ DisplayText = "多行文本(MTEXT)", EntityName = "MTEXT"}, }; _chkEntityTypes.Items.Clear(); foreach (var item in entityList) { _chkEntityTypes.Items.Add(item); }界面效果:列表里用户看到插入块(INSERT),可读性很好,括号带上英文方便查问题。
3. 获取选中项(直接拿到英文,无需映射)
// 获取所有勾选的CAD实体英文名称 List<string> selectedEntityNames = new List<string>(); for (int i = 0; i < _chkEntityTypes.CheckedItems.Count; i++) { var itm = _chkEntityTypes.CheckedItems[i] as EntityTypeItem; if(itm != null) { selectedEntityNames.Add(itm.EntityName); } } // selectedEntityNames 里面直接就是 ["INSERT","LINE"...],直接给CAD逻辑用备选方案对比
方案A:上面对象方案(✅推荐)
- 用户看中文(可附带英文备注)
- 代码直接取英文,不用字典映射、不用字符串翻译
- 不需要维护外部说明文档
- 序列化/保存配置的时候,直接存
EntityName字段即可
方案B:界面显示中文,维护一个字典做中英文映射
Dictionary<string, string> dict = new Dictionary<string, string>() { {"插入块","INSERT"}, {"直线","LINE"}, };缺点:来回查表;新增类型要同时改两处,容易漏,容易bug。
方案C:界面直接显示英文,写说明文档
适合工具是内部工具,使用者懂CAD;缺点:小白上手懵。
方案D:显示中文(英文),就是示例代码里的写法
兼顾小白与开发调试,出日志、截图的时候英文也看得见,非常适合CAD工具。
扩展:如果需要保存/加载勾选状态
保存配置时只保存EntityName字符串集合;加载时遍历 Items,匹配EntityName设置勾选状态。
//加载勾选 var saveNames = new HashSet<string>{"INSERT","LINE"}; for(int i=0;i<_chkEntityTypes.Items.Count;i++) { var obj = _chkEntityTypes.Items[i] as EntityTypeItem; _chkEntityTypes.SetItemChecked(i, saveNames.Contains(obj.EntityName)); }小坑提醒
CheckedListBox不要用DataSource,很多版本下CheckedListBox绑定DataSource后勾选状态容易出诡异bug;优先用Items.Add()添加对象,就是上面示例写法。
如果你想,我可以把这一段整理成可直接复制进你项目的完整片段。