C# 如何解决两个不同自定义类绑定的ListBox跨移选中项时的类型转换错误
问题根因
你定义的Classgreat与Classskill是两个完全独立的自定义引用类型,哪怕两者的属性结构、字段值100%一致,C# 的强类型系统也会将其识别为互不兼容的不同类,不支持直接互相强制转换。
出现报错的核心原因是你写跨ListBox移动项的逻辑时,直接把源ListBox取出的选中项(比如Classgreat实例)强转为目标ListBox对应的Classskill类型,直接触发了类型不匹配的异常。
可落地的解决方案
方案1:抽公共统一实体(最推荐,一劳永逸)
两个类除了类名不同没有任何结构差异,重复定义完全没有必要,直接抽一个通用实体类作为两个列表的共用类型,从根源上消除类型不兼容的问题:
- 删除原有两个独立的
Classgreat、Classskill类,新建统一的实体类:
/// <summary>两个ListBox共用的机台线路项实体</summary> public class MachineLineItem { public int machid { get; set; } public string lm { get; set; } public int idline { get; set; } }
- 原有数据库查询逻辑只需要把
new Classskill()、new Classgreat()替换成new MachineLineItem()即可,属性赋值逻辑完全不用改动;两个泛型列表的类型同步换成List<MachineLineItem>。 - 跨ListBox移动选中项时,因为两边数据源是完全相同的类型,直接取出选中项从原列表移除、添加到目标列表,再重新绑定数据源即可,全程不需要任何类型转换,彻底避免转换报错。
方案2:保留两个独立类,移动时手动做属性映射
如果因为历史代码耦合度高,没法一下子删掉两个独立类,不要对取出的选中项做强转操作,逐属性手动映射生成目标类的实例即可:
- 举个从skill绑定的ListBox移项到great绑定的ListBox的参考代码:
// 从源ListBox取出选中的skill类型对象,这一步取自己数据源的类型是不会报错的 var selectedSkillItem = (Classskill)listBoxrole.SelectedItem; // 手动新建目标类型实例,逐属性赋值,绝对不要直接强转 var newGreatItem = new Classgreat() { machid = selectedSkillItem.machid, lm = selectedSkillItem.lm, idline = selectedSkillItem.idline }; // 将newGreatItem添加到great对应的泛型列表后,重新绑定ListBox数据源即可
容易踩的小坑
- 移项操作完成后,记得给对应ListBox触发绑定刷新(直接重新给DataSource赋值即可,不需要额外复杂操作),否则界面不会同步显示移动后的结果
- 无论用哪种方案,ListBox设置的
DisplayMember、ValueMember属性名要和实体类的属性名完全匹配,否则会出现ListBox里直接显示类全名、而不是实际需要的lm字段值的问题
内容的提问来源于stack exchange,提问作者Mehrdad b.h
相关产品推荐
相关产品推荐

