Simon
Simon

Reputation: 81

Listbox is displaying class name instead of values

I'm working on a project where the user is supposed to input values to animal (Name, age, gender etc..) and the values entered by the user are supposed to display on a list-box The classes inherit from each other. Here is how the inheritance work:

Animal class is the parent for all classes.

Mammal class inherit from Animal class.

Dog class inherit from Mammal class.

Cat class inherit from Mammal class

Reptile class inherit from Animal class

Snake class inherit from Reptile class

Lizard class inherit from Reptile class

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 that depending on the type of animal selected by the user, it displays its animals.

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.

The problem is that when the user enters the animal values (Name and Age) after selecting the animal type in the listbox(for example Mammal, Dog) and clicks the add button, the result listbox displays Assign1_1.Mammal when trying to add a Mammal animal and Assign_1.Reptile when trying to add a Reptile animal.

What I want it to do is to display the values the user entered (Name and Age) in the result listbox but instead it just says Assign1.Mammal or Assign1.Reptile depending on the selected animal.

Here is my MainForm code:

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();
        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();
        }
        private int ReadAge()
        {
            int age = 0;

            int.TryParse(Agetxt.Text, out age);

            return age;
        }

        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();
                        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();

            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);

                Resultlst.Items.Add(animal.ToString());
            }
        }

Here is my Animal manager class:

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_animal;
        private List<Mammal> m_mammal;
        public AnimalManager()
        {
            //In this list objects off diff animals of all species are saved
            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, why do I need type casting when copying?
        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; }
        }


    }
}

Here is my mammal class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Assign_1
{
    class Mammal : Animal
    {
        private MammalType theMammal;
        private int teeth;


        public Mammal() : base()
             {

             }
        public Mammal(Animal other)
        {
            this.Name = other.Name;
            this.Age = other.Age;
            this.Gender = other.Gender;
            this.Id = other.Id;

        }

        public Mammal (MammalType type)
        {
            theMammal = type; 
        }

#region Props
        public MammalType TheMammal
        {
            get { return theMammal; }
            set { theMammal = value; }
        }


        public int Teeth
        {
            get { return teeth; }
            set { teeth = value; }
         }
#endregion


    }
}

Here is my Dog class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Assign_1
{
    class Dog : Mammal
    {


        public Dog()
        {

        }
      public Dog(Mammal other)
    {
      this.Name = other.Name;
      this.Age = other.Age;
      this.Teeth = other.Teeth;
    }


    }
}

EDIT To do this simpler, I'm only showing child class Mammal and Dog. If I'm able to figure out how to create a Dog, I can probably fix the others as well.

Upvotes: 3

Views: 1689

Answers (2)

Hjalmar Z
Hjalmar Z

Reputation: 1601

You need to override the ToString()-method. Note the override keyword in the signature.

public override string ToString()
{
    //You can put anything here and it will be returned by the ToString()-method.
    return this.Name + ", " + this.Age;
}

Put this code in your Dog-class. It will make dog.ToString() return Name, Age.

Also, you can actually put this override in your base class, Animal, and it will be carried over to all the subclasses. As long as they don't override ToString() themselves they will also return Name, Age.

Upvotes: 5

Steve
Steve

Reputation: 216353

You simply need to add an override of the ToString() method in your classes.
The override returns the value that you choose to display in your ListBoxes.

The ListBox, when is ready to display the items, use the ToString method of the class instance that is added to its items collection. If there is no ToString() then the base class Object.ToString() is used and that method returns just the class name

For example you could change the Dog class with

class Dog : Mammal
{
    public Dog()
    {
    }
    public Dog(Mammal other)
    {
       this.Name = other.Name;
       this.Age = other.Age;
       this.Teeth = other.Teeth;
    } 
    public override string ToString()
    {
       return string.Format("{0}, {1}, {2}", 
               this.Name, this.Age, this.Teeth);
    }
}

Upvotes: 4

Related Questions