Link to home
Start Free TrialLog in
Avatar of igor92128
igor92128

asked on

C# Scoping Question

My problem is that I have 2 different forms and in 1 form I have an empty listbox, and in the other form I have the user input information that copies an object and goes into ArrayList. I can't access the ArrayList in the other form, where I have my listbox. Here is the code:

namespace StudentScores
{
      
      public class MainForm : System.Windows.Forms.Form
      {
      
            public System.Windows.Forms.ListBox mainList;
            
            private System.ComponentModel.Container components = null;

            public MainForm()
            {
                  
            
                  InitializeComponent();

            
            }

            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if (components != null)
                        {
                              components.Dispose();
                        }
                  }
                  base.Dispose( disposing );
            }

            #region Windows Form Designer generated code
            ///
            #endregion

            [STAThread]
            static void Main()
            {
                  Application.Run(new MainForm());
            }

            private void btnExit_Click(object sender, System.EventArgs e)
            {
                  this.Close();
            }

            private void btnAdd_Click(object sender, System.EventArgs e)
            {
                  AddStudent newStudentForm = new AddStudent();
                  newStudentForm.ShowDialog();
            }

            public void FillStudentListBox()
            {

ERROR -->      foreach(Student s in students) // Compiler says that students cannot be found
                  {
                        mainList.Items.Add(s.DisplayText());
                  }
            }
      }
}


namespace StudentScores
{
      
      public class AddStudent : System.Windows.Forms.Form
      {
            ArrayList students = new ArrayList();
            
            private System.ComponentModel.Container components = null;

            public AddStudent()
            {      
                  InitializeComponent();
            }

      
            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if(components != null)
                        {
                              components.Dispose();
                        }
                  }
                  base.Dispose( disposing );
            }

            #region Windows Form Designer generated code
            ///
            #endregion

            private void btnCancel_Click(object sender, System.EventArgs e)
            {
                  this.Close();
            }

               // I want the listbox to be populated with students ArrayList content
            private void stuAdd_Click(object sender, System.EventArgs e)
            {
                  Student stu = new Student(txtName.Text, txtScore.Text);
                  students.Add(stu);
                  this.Close();
            }

      }
      
}

// This is my Students Class File
namespace StudentScores
{
      /// <summary>
      /// Summary description for Student.
      /// </summary>

      public class Student
      {
            

            public string Name;
            public string Scores;

// constructor
            public Student(string name, string scores)
            {
                  this.Name = name;
                  this.Scores = scores;
            }

            public string DisplayText()
            {
                  return Name + ", " + Scores;
            }
      }
}

Any ideas on how to solve this problem?
Avatar of vo1d
vo1d
Flag of Germany image

do you need the information from that newStudentForm instance?

private void btnAdd_Click(object sender, System.EventArgs e)
          {
               AddStudent newStudentForm = new AddStudent();  //<-- this one?
               newStudentForm.ShowDialog();
          }


if so, you will have to change your close() methods of the AddStudent form to the hide() methods and you also have to setup the dialogresults for that form.
then change your fielddeclaration of your students arraylist of the AddStudentForm like this:
internal ArrayList students = new ArrayList();

after that, change the btnAdd_Click eventhandler of MainForm like this:
private void btnAdd_Click(object sender, System.EventArgs e)
{
  AddStudent newStudentForm = new AddStudent();
  if(newStudentForm.ShowDialog() == DialogResult.OK) //<-- asume you close the addstudent form with the ok result
  {
    foreach(object s in newStudentForm.students) // Compiler says that students cannot be found
    {
      mainList.Items.Add((s as Student).DisplayText());
    }
  }
}
Avatar of aaronfeng
aaronfeng

Just a side note, your DisplayText() looks like it should just be ToString().  Of course, it doesn't have to be.  The benifit of overriding the ToString() is that the function will be called implicitly when you are trying to output the Student object.

If you are interesting, inside of your Student object you would do something like this:

public override string ToString() {
  return Name + ", " + Scores;
}

Cheers,

Aaron
http://aaronfeng.blogspot.com/
Ok, I have remodelled your solution and this is how I achieve forms to communicate

1.  add the 2 interfaces below to your project

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace StudentScores
{
    public interface IStudent
    {
        ArrayList Students { get;}
    }
}

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace StudentScores
{
    public interface iParentForm
    {
        Form MyParentForm { set;}
    }
}

2.  Implement IStudent interface in the MainForm as shown below

change class declaration to this
public class MainForm  : Form, IStudent

delete the arrayList declaration from Addstudent form and stick the code below in the MainForm  

        ArrayList students = new ArrayList();

        public ArrayList Students
        {
            get { return students; }
        }

3.  Implement iParentForm interface in the AddStudent form as shown below

Stick this implementation of the interface in AddStudent  form

        Form myParentForm = null;

        public Form MyParentForm
        {
            set { myParentForm = value; }
        }

4.  Change the code in the stuAdd_Click in AddStudent  form to this

            Student stu = new Student(txtName.Text, txtScore.Text);
            ((IStudent) this.myParentForm).Students.Add(stu);
            this.Close();

5.  Change the btnAdd_Click code in MainForm form to this

            AddStudent newStudentForm = new AddStudent();
            newStudentForm.MyParentForm = this;
            newStudentForm.ShowDialog();
            FillStudentListBox();

6.  Change the FillStudentListBox code in MainForm form to this

            this.mainList.Items.Clear();  
            foreach (Student s in students)
            {
                mainList.Items.Add(s.DisplayText());
            }

That is it.  May sound like over done but it is elegant solution IMHO

If you don't understand any if this please ask.  hope i haven't left anything out.  I actually recreated the whole project but i am using VS2005 and it uses partial classes to seperate code, so it is not easy to just copy whole code

cheers
Avatar of igor92128

ASKER

Isn't there a simple way of doing this without having to re-write the entire program? Maybe there is a way of getting this to work by changing a line or 2. I've been experimenting with inheritance but I haven't got that work yet. I have VS 2003.

vo1d, that didn't work because:

private void stuAdd_Click(object sender, System.EventArgs e)
            {
                  Student stu = new Student(txtName.Text, txtScore.Text);
                  this.Parent(students.Add(stu)); // Error: students cannot be found
                  this.Close();
            }

This is where I still get the error.
Here is what the program is supposed to do:

1. When the program launches, it displays an empty listbox and an "add..." button in the MainForm form.
2. Clicking on the "Add..." button will take the user to the AddStudent form.
3. The user enters the student's name and score into the form and it gets written to the stu object and added into the students ArrayList.
4. After this, user is sent back to MainForm, where the students ArrayList contents are updated and displayed in the listbox.

Thanks.
ASKER CERTIFIED SOLUTION
Avatar of vo1d
vo1d
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
the button of the stuAdd_Click eventhandler has to be setuped for dialogresult.ok .
Ok, I've changed the program and it compiles now.  But, after clicking the "Add..." button in the AddStudent form, the listbox is not being updated with the new student and it's empty.
Ok, I got it to work, I just changed the method to this:

private void btnAdd_Click(object sender, System.EventArgs e)
                        {
                              this._studentForm = new AddStudent();
                              _studentForm.ShowDialog();      
            
                              foreach(object s in this._studentForm.students)
                              {
                                    mainList.Items.Add(s.ToString());
                              }
                        }