列表框无法显示子类变量 [英] Listbox cannot display child class variable
问题描述
我正在开发一个项目,其中用户输入动物的值(姓名、年龄、性别等),并且用户输入的值显示在列表框中这些类相互继承.以下是继承的工作原理:
I'm working on a project where the user is inputing values to animal (Name, age, gender etc..) and the values entered by the user are displayed on a list-box The classes inherit from each other. Here is how the inheritance work:
Animal 类是所有类的父类.
Mammal 类继承自 Animal 类.
Dog 类继承自 Mammal 类.
Cat 类继承自 Mammal 类
Reptile 类继承自 Animal 类
Snake 类继承自 Reptile 类
Lizard 类继承自 Reptile 类
Animal 的变量是 id、name、age、gender.
The variables for Animal is id, name, age, gender.
哺乳动物的变量是牙齿
Dog 的变量是 barkLevel
用户可以选择要创建的动物.有一个列表框显示动物的类型(哺乳动物和爬行动物),旁边有一个列表框,根据用户选择的动物类型,它会显示其动物.
The user is able to choose what animal to create. There is one listbox showing the type of animal (Mammal and Reptile) and there is a listbox next to it that depending on the type of animal selected by the user, it displays its animals.
例如,如果用户在列表框中选择Mammal,它旁边的列表框将显示Dog 和Cat.
For exampel, if the user selects Mammal in the listbox, the listbox next to it displays Dog and Cat.
这是完美的工作,这不是问题.
This is working perfectly and it's not the problem.
问题:
输入值显示在结果列表中,但不显示子类变量.结果列表框正在显示Id、姓名、年龄、性别但>不是 牙齿或barkLevel.没有错误消息或任何东西.它只是不显示子类变量.
The input values are being displayed on the result list, but not the child class variables. The result listbox is displaying Id, Name, Age, Gender but not teeth or barkLevel. There are no error messages or anything. It just doesn't display the child class variables.
这是我的主窗体:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Assign_1
{
public partial class MainForm : Form
{
private Dog m_dog = new Dog();
private Cat m_cat = new Cat();
private Snake m_snake = new Snake();
private Lizard m_lizard = new Lizard();
private AnimalManager animalmgr = null;
private Animal m_animal = new Animal();
private Mammal m_mammal = new Mammal();
public MainForm()
{
//Visual Studio initializations
InitializeComponent();
//My initializations
InitializeGUI();
Gendercmb.DataSource = Enum.GetValues(typeof(GenderType));
Categorylst.DataSource = Enum.GetValues(typeof(Categorytype));
animalmgr = new AnimalManager();
}
private void InitializeGUI()
{
ReadInput();
}
private void ReadInput()
{
m_animal.Name = ReadName();
m_animal.Age = ReadAge();
m_mammal.Teeth = ReadTeeth();
m_dog.BarkLevel = ReadBarklevel();
m_animal.Gender = this.Gendercmb.GetItemText(this.Gendercmb.SelectedItem);
}
private int ReadAge()
{
int age = 0;
int.TryParse(Agetxt.Text, out age);
return age;
}
private int ReadBarklevel()
{
int bark = 0;
int.TryParse(barktxt.Text, out bark);
return bark;
}
private int ReadTeeth()
{
int teeth = 0;
int.TryParse(teethtxt.Text, out teeth);
return teeth;
}
private string ReadName()
{
string name = "";
name = Nametxt.Text;
return name;
}
private void addMammal(Mammal values)
{
ReadInput();
switch ((MammalType)Animallst.SelectedIndex)
{
case MammalType.Dog:
{
// Use a copy constructor to set a dog with common data
Dog m_dog = new Dog(values);
// If more data in GUI to fill in for this animal, do it here
//Then send it to the manager for adding to the list
animalmgr.add(m_dog);
break;
}
case MammalType.Cat:
{
Cat m_cat = new Cat(values);
animalmgr.add(m_cat);
break;
}
}
}
private void AddReptile(Reptile values)
{
ReadInput();
switch ((ReptileType)Animallst.SelectedIndex)
{
case ReptileType.Snake:
{
// Use a copy constructor to set a snake with common data
Snake m_snake = new Snake(values);
// If more data in GUI to fill in for this animal, do it here
//Then send it to the manager for adding to the list
animalmgr.add(m_snake);
break;
}
case ReptileType.Lizard:
{
Lizard m_lizard = new Lizard();
animalmgr.add(m_lizard);
break;
}
}
}
//When user clicks "Add to list"
private void button1_Click(object sender, EventArgs e)
{
ReadInput();
System.Windows.Forms.MessageBox.Show(m_dog.BarkLevel.ToString());
switch ((Categorytype)Categorylst.SelectedIndex)
{
case Categorytype.Mammal:
{
Mammal mammal = new Mammal(m_animal);
addMammal(mammal);
break;
}
case Categorytype.Reptile:
{
Reptile m_reptile = new Reptile(m_animal);
AddReptile(m_reptile);
break;
}
}
UpdateResults();
}
private void UpdateResults()
{
Resultlst.Items.Clear(); //Erase current list
//Get one elemnet at a time from manager, and call its
//ToString method for info - send to listbox
for (int index = 0; index < animalmgr.ElementCount; index++)
{
Animal animal = animalmgr.GetElementAtPosition(index);
toString method.
Resultlst.Items.Add(animal.ToString()); // <--- Here is the problem
}
}
}
}
这是我的动物经理类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assign_1
{
class AnimalManager
{
// private List<Animal> m_animalList;
private List<Animal> m_animal;
private List<Mammal> m_mammal;
public AnimalManager()
{
//In this list objects off diff animals of all species are saved
// m_animalList = new List<Animal>();
m_animal = new List<Animal>();
m_mammal = new List<Mammal>();
}
public void add(Animal ObjIn)
{
m_animal.Add(ObjIn);
}
public bool IsIndexValid(int index)
{
return ((index >= 0) && (index < m_animal.Count));
}
public Animal GetElementAtPosition(int index)
{
//We choose to return a copy
if (IsIndexValid(index))
{
if (m_animal[index] is Mammal)
return new Mammal((Mammal)m_animal[index]);
if (m_animal[index] is Reptile)
return new Reptile((Reptile)m_animal[index]);
return null;
}
else
return null;
}
public int ElementCount
{
get { return m_animal.Count; }
}
}
}
更新:
我现在知道问题出在 Resultlst.Items.Add(animal.ToString());
不知何故我需要包含哺乳动物和狗对象(取决于所选动物)但我不不知道如何.
I know now that the problem is Resultlst.Items.Add(animal.ToString());
Somehow I need to include the mammal and dog object (depending on the selected animal) but I don't know how.
推荐答案
据我所知,您实际上从未真正返回过您的子类.假设您在 m_animal
中拥有所有的猫、狗、蛇和蜥蜴,当您通过基类构造函数运行它们时,您实际上丢失了子类的属性.尝试直接返回对象:
From what I can tell you're never actually returning your sub classes. Assuming you've got all your cats, dogs, snakes and lizards in m_animal
, when you run them through the base class constructors you are actually losing the properties of the sub classes. Try returning the objects directly:
public Animal GetElementAtPosition(int index)
{
if (IsIndexValid(index))
return m_animal[index];
else
return null;
}
如果您在所有类中都重写了 ToString()
,您应该会得到您期望的结果.
Provided you have ToString()
overridden in all your classes you should be getting the result you're expecting.
这篇关于列表框无法显示子类变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!