Winforms ListBox如何正确获取选中项对应的自定义Animal对象
问题原因
你向ListBox的Items集合添加的是手动拼接的格式化字符串,而非Animal类型的实体对象,因此AnimalList.SelectedItem拿到的永远是string类型,执行as Animal类型转换时自然会返回null。
修复方案
方案1:重写实体类ToString方法(最简便)
- 首先修改Animal基类(或Dog子类),重写ToString方法,返回你需要在列表中展示的格式化内容:
public class Animal { // 保留你原有定义的所有属性 public string AnimalName { get; set; } public int Happiness { get; set; } public int Tierdness { get; set; } public int Hungriness { get; set; } public string Play() { // 原有Play方法逻辑 } // 新增重写的ToString方法 public override string ToString() { return $"{GetType().Name} {AnimalName} Lycka: {Happiness} Trötthet: {Tierdness} Hunger: {Hungriness} "; } }
- 调整向ListBox添加项的逻辑,直接添加实体对象即可,ListBox会自动调用ToString方法渲染显示内容:
petList.Add(new Dog(animalName)); var addedPet = petList.Last(); // 直接添加实体对象,不需要手动拼接字符串 AnimalList.Items.Add(addedPet);
- 原有点击事件中的类型转换逻辑不需要修改,即可正常拿到Animal类型的实体对象。
方案2:数据源绑定(适合不需要修改实体类定义的场景)
- 先给Animal类新增一个只读的显示属性(不修改原有业务逻辑):
public class Animal { // 原有属性定义不变 public string DisplayText { get => $"{GetType().Name} {AnimalName} Lycka: {Happiness} Trötthet: {Tierdness} Hunger: {Hungriness} "; } }
- 把petList作为ListBox的数据源绑定,指定显示字段:
petList.Add(new Dog(animalName)); AnimalList.DisplayMember = "DisplayText"; // 指定界面显示的属性 AnimalList.DataSource = petList;
如果需要列表内容随petList的修改自动同步,可以把petList的类型从List<Animal>换成BindingList<Animal>。
- 点击事件中的类型转换逻辑同样不需要修改,可直接获取实体对象。
内容的提问来源于stack exchange,提问作者Tobias Axbard
相关产品推荐
相关产品推荐

