C# WinForm 如何高效将ListView勾选项的Tag或名称展示到ListBox
问题根源
你当前遇到的带前缀的显示效果,本质是直接向ListBox.Items添加ListViewItem对象时,ListBox会默认调用对象的ToString()方法生成展示文本。而WinForm内置的ListViewItem.ToString()是面向调试场景设计的,默认输出格式固定为类名: "项文本",刚好就是你看到的{listViewItem}: "项名称"效果,本身就不是为面向用户的UI展示设计的。
直接依赖控件默认ToString方法做展示属于反模式,既容易出现和预期不符的格式,改动控件原生行为还可能引入不可预期的问题。
高效实现方案
根据你是否需要在后续操作中关联回原始ListView项,选择对应方案即可,两种方案都没有冗余的性能损耗:
方案1:仅需要展示文本,无需反查原始对象
该方案性能最高,无额外对象引用开销,适合只需要同步展示项名称/Tag值、不需要后续和原ListView联动操作的场景。只需要在循环中提取需要展示的内容完成添加即可,改造成本极低:
listBox1.Items.Clear(); foreach (ListViewItem item in listView1.CheckedItems) { // 要展示项本身的名称时,使用这行代码 listBox1.Items.Add(item.Text); // 要展示项绑定的Tag属性值时,替换上面的Add代码 // 加空判断避免Tag为null时抛出异常 // listBox1.Items.Add(item.Tag?.ToString() ?? string.Empty); }
方案2:展示自定义文本,同时需要保留原始ListViewItem的关联
如果后续操作ListBox时,还需要定位回对应的ListView项(比如修改选中样式、读取关联的其他属性),不要直接存纯字符串靠文本匹配查找(重名场景下会出错,也存在遍历匹配的性能损耗)。可以使用轻量值元组同时存储展示内容和原始对象引用,配合ListBox的显示字段映射实现规范展示:
- 窗体初始化时配置一次ListBox的显示规则即可,后续添加的所有项都会自动按规则渲染:
// 指定ListBox从添加的对象里取DisplayText字段做显示文本 listBox1.DisplayMember = "DisplayText";
- 替换循环中的添加逻辑:
listBox1.Items.Clear(); foreach (ListViewItem item in listView1.CheckedItems) { // 元组第一个值是要展示的内容,换成item.Tag?.ToString()即可切换为展示Tag值 // 第二个值是原始ListViewItem的直接引用,后续可以通过选中项直接读取,无查找成本 listBox1.Items.Add(( DisplayText: item.Text, SourceItem: item )); }
这种方式完全避开了默认ToString的显示逻辑,不会出现类名前缀的问题。
额外优化
如果需要同步的勾选项数量超过上千条,可以在数据同步期间临时关闭ListBox的重绘逻辑,避免界面闪烁:
listBox1.BeginUpdate(); // 此处放清空列表、循环添加项的业务逻辑 listBox1.EndUpdate();
内容的提问来源于stack exchange,提问作者Yule
相关产品推荐
相关产品推荐

