I have troubles trying to display a list of items/objects in a array.

What I'm doing is I'm adding students with a name, surname, age, and marks for subjects (Properties) to an array. If I added 4 students in this manner to the list I want to display all the students with their properties again in the richTextBox when the Display button is clicked.

How do I go about it in the "displayAll_Click" function?? Must I use a for loop of some sort?? Any help will be appreciated.

I have the following code:

In this fucntion I'm adding the student into the array:

private void btnAdd_Click(object sender, EventArgs e)
    {
        // Create new student and assign name etc provided by user
        Student _Student = new Student();
        _Student.Name = txtName.Text;
        _Student.Surname = txtSurname.Text;
        _Student.Age = Convert.ToInt32(txtAge.Text);
        _Student.ITMark = Convert.ToInt32(txtIT.Text);
        _Student.MathMark = Convert.ToInt32(txtMath.Text);
        _Student.EngMark = Convert.ToInt32(txtEng.Text);

        MessageBox.Show("Student added.");

        // Increase counter and display how many students added so far
        CountStudents++;

        Average = Convert.ToInt32(txtIT.Text) + Convert.ToInt32(txtMath.Text) + Convert.ToInt32(txtEng.Text);
        _Student.AverageMark = Average / 3;

        //Add the newly added student to the ClassList array
        ClassList[CountStudents - 1] = _Student;

        //Clear the list after student is added
        txtAge.Clear();
        txtName.Clear();
        txtSurname.Clear();
        txtIT.Value = 0;
        txtMath.Value = 0;
        txtEng.Value = 0;
        txtName.Focus();
    }

And in this function I want to display it that was added in the array or list?

private void displayAll_Click(object sender, EventArgs e)
        {
            List<Student> _StudentList = new List<Student>();

            Student _Student = new Student();
            _Student.Name = txtName.Text;
            _Student.Surname = txtSurname.Text;
            _Student1.Age = Convert.ToInt32(txtAge.Text);
            _Student.ITMark = Convert.ToInt32(txtIT.Text);
            _Student.MathMark = Convert.ToInt32(txtMath.Text);
            _Student.EngMark = Convert.ToInt32(txtEng.Text);

            for (int i = 0; i < _StudentList; i++)
            {
                richTextBox1.Text = ("Student: " + Convert.ToString(CountStudents) +
                                 "\nName: " + _Student.Name +
                                "\nSurname: " + _Student.Surname +
                                 "\nAge: " + _Student.Age +
                                 "\nStudent Average: " + Convert.ToString(_Student.AverageMark));
                i++;
            }
            //Displaying all the students
            MessageBox.Show("Display all students.");
        }

If you use a 'foreach' or 'for' loop you can simply pass the values from the list. You don't need to create a new Student object in your display method. You also do not need to increment your iterator (i) within the for loop. The 'i++' part of the 'for' loop does this for you. Like ddanbe suggested, I would recommend a 'foreach' loop for your situation...

foreach(var student in _StudentList){
    richTextBox1.Text += "Student: " + student.Name + ...   
}

...but if you must use a simple 'for' loop...

for(int i = 0;i<_StudentList.Length;i++){
    richTextBox1.Text += "Student: " + _StudentList[i].Name + ...
}

You may want to review This MSDN Article about 'for' loops.

Hope this helps. :-)

-pH

Ok well I tried the following code since Im storing every student in the array. But then it gives me a very weird error stating that the object reference is not set to an instance of an object??

private void displayAll_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
            for (int i = 0; i < ClassList.Length; i++)
            {
                richTextBox1.Text += ("Student: " + Convert.ToString(i) +
                                 "\nName: " + ClassList[i].Name +
                                "\nSurname: " + ClassList[i].Surname +
                                 "\nAge: " + ClassList[i].Age +
                                 "\nStudent Average: " + Convert.ToString(ClassList[i].AverageMark));
            }

            MessageBox.Show("Display all students.");
        }

Edited 2 Years Ago by Joemeister

On which line the error occurs and what tells the message exactly?
Btw. Convert.ToString(ClassList[i].AverageMark)); is the same as
ClassList[i].AverageMark.ToString();

Okay it is very difficult to explain but it highlights the whole richTextBox1 function in yellow (Im using Visual Studio 2008) and it says that NullReferenceException is handled and that Object reference is not set to an instance of an object???

Also The array's size is 50 and when I run the loop where I use 'i < ClassList.Count()' it sees it as 50 and not the amount of students I created? Why is that?

You seem to mix up your classList array with the StudentList, I should throw away one of them.
richTextBox1 could be ok as it is probably created with the toolbox. Is that correct?

Okay I have updated code where I removed the list and only work with the array. It still gives me the "NullReferenceException is handled" and the "Object reference is not set to an instance of an object" error.

What precisely must I do with ClassList[] regarding "new" if I want to use it?

namespace A4
{
    public partial class frmAddStudent : Form
    {
        public frmAddStudent()
        {
            InitializeComponent();
        }

        // Declare variables to be used by both event handlers
        int CountStudents = 0;
        double Average = 0;
        Student[] ClassList = new Student[50];

        private void btnAdd_Click(object sender, EventArgs e)
        {
            // Create new student and assign name etc provided by user
            Student _Student = new Student();
            _Student.Name = txtName.Text;
            _Student.Surname = txtSurname.Text;
            _Student.Age = Convert.ToInt32(txtAge.Text);
            _Student.ITMark = Convert.ToInt32(txtIT.Text);
            _Student.MathMark = Convert.ToInt32(txtEng.Text);
            _Student.EngMark = Convert.ToInt32(txtMath.Text);

            // Use the hasPassed method to display an appropriate message after the 
            // student has been added
            MessageBox.Show("Student added.");

            // Increase counter and display how many students added so far
            CountStudents++;

            Average = Convert.ToInt32(txtIT.Text) + Convert.ToInt32(txtEng.Text) + Convert.ToInt32(txtMath.Text);
            _Student.AverageMark = Average / 3;



            //Display Student's properties
            richTextBox1.Text += ("Student: " + Convert.ToString(CountStudents) +
                                 "\nName: " + _Student.Name +
                                 "\nSurname: " + _Student.Surname +
                                 "\nAge: " + _Student.Age +
                                 "\nStudent Average: " + Convert.ToString(_Student.AverageMark) + "\n" + "\n");


            //Add the newly added student to the ClassList array
            ClassList[CountStudents - 1] = _Student;

            //Clear the list
            txtSurname.Clear();
            txtName.Clear();
            txtAge.Clear();
            txtIT.Value = 0;
            txtEng.Value = 0;
            txtMath.Value = 0;
            txtName.Focus();
        }

        private void btnAverage_Click(object sender, EventArgs e)
        {
            double TotalMarksIT = 0.0;
            double TotalMarksMath = 0.0;
            double TotalMarksEng = 0.0;
            int i;

            // Go through ClassList array and calculate total marks
            for (i = 0; i < CountStudents; i++)
                TotalMarksIT += ClassList[i].ITMark;

            for (i = 0; i < CountStudents; i++)
                TotalMarksMath += ClassList[i].MathMark;

            for (i = 0; i < CountStudents; i++)
                TotalMarksEng += ClassList[i].EngMark;

            // Calculate average and display
            richTextBox1.Text = ("IT: " + Convert.ToString(TotalMarksIT / CountStudents)
                + "\nMath: " + Convert.ToString(TotalMarksMath / CountStudents)
                + "\nEnglish: " + Convert.ToString(TotalMarksEng / CountStudents));

            MessageBox.Show("Averages successfully calculated.");

        }

        private void clearList_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
            txtSurname.Clear();
            txtName.Clear();
            txtAge.Clear();
            txtIT.Value = 0;
            txtEng.Value = 0;
            txtMath.Value = 0;
            txtName.Focus();

            MessageBox.Show("List Cleared.");

        }

        private void btnLoadStudent_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Not Working :(");
        }

        private void displayAll_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
            for (int j = 0; j < ClassList.Count(); j++)
            {
                richTextBox1.Text += ("Student: " + Convert.ToString(j) +
                                     "\nName: " + ClassList[j].Name +
                                     "\nSurname: " + ClassList[j].Surname +
                                     "\nAge: " + ClassList[j].Age +
                                     "\nStudent Average: " + Convert.ToString(ClassList[j].AverageMark) +
                                     "\n" + "\n");
            }

            //MessageBox.Show("Display all students.");
        }
    }
}

Only look at the "displayAll" function. The rest is just for you to see what I'm doing so far. :)

If you are initializing an array with the size of 50 ClassList.Count() will always be fifty no matter how many Students you add to the list. This means that your 'for' loop is looking at null positions. Here are a couple of suggestions to try.

First, since you already have a 'counter' for the number of students that have been added you can use it in place of the 'ClassList.Count()' in your 'for' loop on line 108.

...
for(int i = 0;i<CountStudents;i++){
    // do work with ClassList[i]...
}

Second, put a check in your 'for' loop to make sure the object in the ClassList[j] position is not null. Simply add a quick check for null.

...
if(ClassList[j] == null) 
    break;  // You can also use continue; if you do want to loop through the entire array.

// do work with ClassList[j]...

I personally suggest using using the second solution as it does not require the counter and it will break out of the loop at the first null position. If there is ever going to be a chance that there are null positions between non-null positions (caused by nulling or deleting a student at a specific position) I would suggest using the 'continue;' statement instead of the 'break;' statement as it will move to the next iteration.

Hope this helps.

-pH

Edited 2 Years Ago by stpatrck: meant to say '..use continue; if you DO want to loop..."

If you are not restricted to using an array you may want to consider List<Student>. This would simplify your code to be something like...

Initialize the list of students

var ClassList = new List<Student>();

Modify your add click to...

private void btnAdd_Click(object sender, EventArgs e)
        {
            // Create new student and assign name etc provided by user
            Student _Student = new Student();
            _Student.Name = txtName.Text;
            _Student.Surname = txtSurname.Text;
            _Student.Age = Convert.ToInt32(txtAge.Text);
            _Student.ITMark = Convert.ToInt32(txtIT.Text);
            _Student.MathMark = Convert.ToInt32(txtEng.Text);
            _Student.EngMark = Convert.ToInt32(txtMath.Text);

            // ... omitted for brevity

            ClassList.Add(_Student);

            // .. clear input controls.
        }

Then no changes are needed to your display method

private void displayAll_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
            for (int j = 0; j < ClassList.Count(); j++)
            {
                richTextBox1.Text += ("Student: " + Convert.ToString(j) +
                                     "\nName: " + ClassList[j].Name +
                                     "\nSurname: " + ClassList[j].Surname +
                                     "\nAge: " + ClassList[j].Age +
                                     "\nStudent Average: " + Convert.ToString(ClassList[j].AverageMark) +
                                     "\n" + "\n");
            }
            //MessageBox.Show("Display all students.");
        }
Comments
for overall effort :)

If you can and may, please use a List!
If you still get the same error, tell us where or how did you define your richTextBox?

Hmmm thanks for that piece of code. I think it will work but its giving me an error regarding the initialization of the list.

The error is as follows:

The contextual keyword 'var' may only appear within a local variable declaration
This question has already been answered. Start a new discussion instead.