Search code examples
c#windowswinformsstreamreaderopenfiledialog

Using OpenFileDialog and StreamReader


There are two classes, one to cover the form (class 1) and the other to cover what gets displayed on the form (class 2). I'm trying to call a method in class 1 from class 2 to display certain information in a text box. I keep getting the error:

An object reference is required for the non-static field, method, or property

I've encountered this error before and been able to make it through, but nothing I've attempted so far has helped in this instance. I'm posting code for both the classes.

Class 1:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;

namespace Project6
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        Stream myStream = null;

        //Create an instance of the open file dialog box
        OpenFileDialog ofd = new OpenFileDialog();

        //Set parameters, filter options, and filter index
        ofd.InitialDirectory = "c:\\";
        ofd.Filter = "Text Files (.txt)|*.txt";
        ofd.FilterIndex = 2;

        ofd.Multiselect = false;

        if (ofd.ShowDialog() == DialogResult.OK)
        {
            try
            {
                if ((myStream = ofd.OpenFile()) != null)
                {
                    using (myStream = ofd.OpenFile())
                    {
                        StreamReader reader = new StreamReader(myStream);

                        string studentInformation = "";
                        string[] studentInformationArray = new string[11];
                        studentInformation = reader.ReadLine();

                        while ((studentInformation = reader.ReadLine()) != null)
                        {
                            studentInformationArray = studentInformation.Split(',');
                            Student newStudent = new Student(studentInformationArray);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: Could not read file from disk.  Original error: " + ex.Message);
            }
        }
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        textBox1.Text = Student.GetName(); //This generates the compiler error
        textBox1.Select(6, 5);
        MessageBox.Show(textBox1.SelectedText);
    }
}
}

Class 2:

using System;
using System.Windows.Forms;

namespace Project6
{
class Student
{
    //Initialize variables
    private string[] studentInformationArray;

    //Constructor that accepts the studentInformationArray as an argument
    public Student(string[] studentInformationArray)
    {
        this.studentInformationArray = studentInformationArray;
    }

    public Student()
    {
        string className = studentInformationArray[1];
        string semester = studentInformationArray[2];
        string picture = studentInformationArray[3];
        int project1 = Convert.ToInt32(studentInformationArray[4]);
        int project2 = Convert.ToInt32(studentInformationArray[5]);
        int project3 = Convert.ToInt32(studentInformationArray[6]);
        int project4 = Convert.ToInt32(studentInformationArray[7]);
        int project5 = Convert.ToInt32(studentInformationArray[8]);
        int project6 = Convert.ToInt32(studentInformationArray[9]);
        int midtermExam = Convert.ToInt32(studentInformationArray[10]);
        int finalExam = Convert.ToInt32(studentInformationArray[11]);
    }

    public string GetName()
    {
        string studentName;
        studentName = studentInformationArray[0];
        return studentName;
    }

}


}

Solution

  • That's because that's not how you use the OpenFileDialog. Take a look at this example hosted by the MSDN here:

    Edit: answering to your edited question. You will always get a NullReferenceException in the Student() constructor because you are never assigning something to your studentInformationArray. So you can fix it like this:

    public Student()
    {
        studentInformationArray = new studentInformationArray[12];
        string className = studentInformationArray[1];
        // rest of your code...
    }
    

    However, you should take into account that studentInformationArray will be an empty array unless you assign something to it. Since you have a Student() overload that takes a string[], I'd suggest you that you either remove the default constructor or make it call the overloaded with default information, like this:

    public Student(string[] studentInformationArray)
    {
         string className = studentInformationArray[1];
         // rest of your code...
         int project1 = int.Parse(studentInformationArray[4]); // always prefer int.Parse() instead of Convert.ToInt32()
         // rest of your code...
         this.studentInformationArray = studentInformationArray;
    }
    
    public Student()
    {
        string[] defaultInformation = new string[12];
        // add information
        defaultInformation[0] = "some information";
        // ...
        new Student(defaultInformation);
    }
    

    Some more points to take into account:

    • Class-level fields/properties should be spelled in Pascal Case (first letter of each word in uppercase, rest in lowercase)
    • Try to never use this.variableName = variableName.
    • Variables names should never include the type of the variable, that's redundant.

    So, for example, change this:

    private string[] studentInformationArray;
    

    for this:

    private string[] StudentInformation;
    

    Answering your last question, regarding the compiler error, you need a reference to the Student read in order to get its name. You could do something like this:

    public partial class Form1 : Form
    {
        private Student StudentRead;
        // rest of your code...
        // from your read method:
        StudentRead = new Student(studentInformationArray); 
    
        // and finally:
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            textBox1.Text = StudentRead.GetName();