0

I'm working on program in c# which uses a listbox as a selection method in its main form. It has functions where you can edit the items in the listbox.

I wanted to edit the items from a seperate dedicated form, so I made a new instance of the form but whenever I try to access the original form's functions (which I have made public) I get this error: Error 2 An object reference is required for the non-static field, method, or property

I've looked around on the internet quite a bit but all I see is people talking about using a static property on my function. However, when I do this I get more of the above errors popping up over variables and the like within the function

Here's the function in Form1 (which i'm trying to reference)

public void ReadConfig(string configFile)
    {
        fileList.Clear();
        listBoxName.Items.Clear();
        FileStream file = null;

        if (!File.Exists(file))
        {
            MessageBox.Show(file + " was not found: Creating blank file");
            using (file = File.Create(file)) ;
        }
        else
        {
            string line;
            int lineNumber = 1;

            // I cut out some long code here where the program reads from a file and saves it to an object
        }
    }

Here's a code snippet for where the error takes place (I cut some code where I save it to a text file, but the main part that's of concern is the Form1.ReadFile(Form1.file)

        private void buttonSave_Click(object sender, EventArgs e)
    {
        string[] temp = File.ReadAllLines(Form1.file);
        string[] newFile;

        if (itemNew == true)
        {
            newFile = new string[temp.Length + 1];
        }
        else
        {
            newFile = new string[temp.Length];
        }

        for (int i = 0; i < temp.Length; i++)
        {
            newFile[i] = temp[i];
        }
        File.WriteAllLines(Form1.file, newFile);
        ConfigForm.ReadFile(Form1.file);


        this.Close();
    }

I hope that's enough code to go off. My program is pretty long so I tried to keep it as short and direct as possible. Thanks for being patient with me =]

I'm pretty new at programming so if any kind souls happen to help could you keep it as simple as possible?

Thanks much =]

  • 1
    Okay. Now show your code where you are getting the error. We can't quite read your screen over the Internet. – JohnFx Apr 23 '12 at 19:05
  • 1
    Please post some code to let people see what you have come up with. – s.m. Apr 23 '12 at 19:05
  • possible duplicate of [Passing data between forms](http://stackoverflow.com/questions/4587952/passing-data-between-forms) – RQDQ Apr 23 '12 at 19:20

3 Answers3

1

It's probably because you're trying to use functions that exist in your first window from the second one as if they were static, but they aren't.

You can try to solve this problem this way:

  • in the second form create a property with class of your first form, like:

    class Form1 : Form
    {
        //this property will store reference to the first form
        public Form1 AssociatedFirstForm { get; set; }
        //...
    }
    
  • Then in the code where you create the second form, assign the first form to this property, which can look like this (if you create the second form from the first one):

    ...
    Form2 secondForm = new Form2();
    secondForm.AssociatedFirstForm = this;
    ...
    

or like this (if you create both forms from another part of code):

    ...
    Form1 firstForm = new Form1();
    Form2 secondForm = new Form2();
    secondForm.AssociatedFirstForm = firstForm;
    ...
  • then, in your second form you should be able to call a method from the first form like this:

    ...
    var myResultFromAnotherWindow = this.AssociatedFirstForm.SampleMethodToCall();
    ...
    

I suppose you should also read more about using static classes and class members and creating instances of objects. It should make it clear to you how and when to use them.

Update

I haven't written it clear enough, but you should avoid to set expose methods or properties as public if it's not really needed.

If you want to create good code structure in your application and learn how it should be done, look for some articles about object oriented programming.

Some sample links:

Knowing eventing mechanism also can be useful: http://msdn.microsoft.com/en-us/library/awbftdfh.aspx.

Lukasz M
  • 5,635
  • 2
  • 22
  • 29
  • So, I realize that this is for a beginner, but the whole "Keep a reference to the mainform and make all methods public" is an anti-pattern if I've ever seen one. A better solution would use events to signal to the parent form that something occurred, allowing it to update its state as needed in response. I just can't give this an upvote as it is currently written. – Ed S. Apr 23 '12 at 19:32
  • I tried this, but now i'm getting a different error. This time, it's Error 2 The item was specified more than once in the "Resources" parameter. Duplicate items are not supported by the "Resources" parameter. I put the associated class at the very top, just above public partial class Form2 : Form I'm not sure if this is the right place, but it has got rid of the original error. Thanks a lot for the help so far =] – Graham Charlesby Apr 23 '12 at 19:39
  • @Ed S.: I'm not telling to make all the methods public, because, as you've already said, it would be against object oriented programming concept. However, if a method (or a property) is a special thing that form does, it can expose it as public, so another form (i.e. its parent form) can use it (like reading `FileName` from `OpenFileDialog` form). Maybe I should've written not to abuse exposing public members within the answer. – Lukasz M Apr 23 '12 at 19:55
  • @Graham Charlesby: It seems that you'are using resources (i.e. *Resources.resx* file) to keep some of your resources. Verify if each of those has got a unique name. – Lukasz M Apr 23 '12 at 19:59
  • I wasn't aware of this, to be honest, I wouldn't even know how to do it in the first place. Have I gone wrong somewhere? =/ – Graham Charlesby Apr 23 '12 at 20:00
  • @Lucas: Well, when I said *all methods* I was generalizing, but my point remains. You are exposing certain properties and methods of a form in order to modify its state, state which probably shouldn't be coupled to another class. It's simply a poor/lazy design and I see it *way* too often. Prefer events. – Ed S. Apr 23 '12 at 20:01
  • @Ed S.: I wrote it for a case when a method/property is called/accessed just to get some data from the other form, without affecting its state at all. I again refer to `OpenFileDialog`. I suppose public property in this particular case is acceptable. However, I agree with you that this can be easily abused and then lead to a messy code structure. – Lukasz M Apr 23 '12 at 20:09
  • @Graham Charlesby: I can't see how the error can be caused by looking at the code you posted. When you double-click on the error, you should be directed to the line causing it. Try to find it this way and then fix it. – Lukasz M Apr 23 '12 at 20:13
  • Thanks for all the help guys, i'm researching eventing now. I need a better grasp of the issues that cause problems really, rather than a quick fix of someone telling me what's wrong with the code. Much appreciated – Graham Charlesby Apr 23 '12 at 21:06
0

You are calling method on type not on instance of a type. When methods are not declared as static you need to first instantiate the object that contains those methods (using new).

Piotr Perak
  • 10,718
  • 9
  • 49
  • 86
0

Here is a basic idea of what you are trying to achieve. A more advanced way of doing it would be with delegates / event handlers but wanted to keep it simple for now.

Form 1

 public Form1()
    {
        InitializeComponent();
    }

    List<string> _items = new List<string>();

    public void LoadListBoxWithItems()
    {
        for (int i = 0; i < 5; i++)
        {
            _items.Add(string.Format("My New Item {0}", i));
        }
        lbItems.DataSource = _items;
        lbItems.Refresh();
    }

    private void btnUpdate_Click(object sender, EventArgs e)
    {
            Form2 form2 = new Form2();
            form2.LoadValues(lbItems.SelectedItem.ToString(), this);
            form2.ShowDialog();
    }

    public string GetCurrentItem()
    {
        return lbItems.SelectedItem.ToString();
    }

    public void UpdateItem(string item, string newitem)
    {
        int index = _items.IndexOf(item);
        _items[index] = newitem;
        lbItems.Refresh();
    }

Form 2

  public Form2()
    {
        InitializeComponent();
    }

    private string _originalvalue = null;
    private Form1 _form1;

    public void LoadValues(string item, Form1 form)
    {
        _originalvalue = item;
        _form1 = form;
    }


    private void btnSave_Click(object sender, EventArgs e)
    {
        // Do work to change value
        string newvalue = _originalvalue;
        _form1.UpdateItem(newvalue, _originalvalue);
    }
tsells
  • 2,751
  • 1
  • 18
  • 20
  • Why xml comments in example code? Especially that they are not finished. – Piotr Perak Apr 23 '12 at 21:33
  • @Peri It's a habit. Most of my code is consumed by others and I have a certain flow that I follow. 1. Write method - once I think it's complete - I add the xml comments section and collapse. 2. Write all tests against code / refactor /etc. Once all the tests are passing - I go back through and fill out the comments / any additional notes that are needed prior to checking in. – tsells Apr 24 '12 at 01:41