?
Solved

C# Scoping Question

Posted on 2006-06-03
8
Medium Priority
?
325 Views
Last Modified: 2010-04-16
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?
0
Comment
Question by:igor92128
8 Comments
 
LVL 11

Expert Comment

by:vo1d
ID: 16826642
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());
    }
  }
}
0
 
LVL 5

Expert Comment

by:aaronfeng
ID: 16826982
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/
0
 
LVL 12

Expert Comment

by:gbzhhu
ID: 16827566
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
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:igor92128
ID: 16828332
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.
0
 
LVL 11

Accepted Solution

by:
vo1d earned 1500 total points
ID: 16828494
 this.Parent(students.Add(stu));
cannot work, because it is a fields of your AddStudent form.
if you wanna get access to it, you will have a reference to a cerated AddStudent form in your mainform.
extend your mailform with the following field:

private AddStudent  _studentForm;


then in your mainforms btnAddClick eventhandler change this:

private void btnAdd_Click(object sender, System.EventArgs e)
{
  if(this._studentForm == null)
  {
    this._studentForm = new AddStudent();
  }
  if(this._studentForm.ShowDialog() == DialogResult.OK) //<-- asume you close the addstudent form with the ok result
  {
    foreach(object s this._studentForm.students) // Compiler says that students cannot be found
    {
      mainList.Items.Add((s as Student).DisplayText());
    }
  }
}

stuAdd_Click of AddStudent change to this:

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


0
 
LVL 11

Expert Comment

by:vo1d
ID: 16828498
the button of the stuAdd_Click eventhandler has to be setuped for dialogresult.ok .
0
 

Author Comment

by:igor92128
ID: 16828595
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.
0
 

Author Comment

by:igor92128
ID: 16828666
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());
                              }
                        }
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
Loops Section Overview
Suggested Courses

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question