tags:

views:

40

answers:

3

I have a simple forms program that I have been fighting with for a while now. I simply want to be able to call a method from a different class file (when a certain step is triggered in the code in that class file) in order to insert a string in the listBox.

Here is my main method, pretty standard:

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());
    }
}

Here is the function which resides in my MainForm.cs file, which I can call just fine from that class file (via 'TextToBox(myString);'):

public partial class MainForm : Form
{
    ...
    // Function to output results to main Listbox window        
    public void TextToBox(string aString)
    {            
        // Place messages in Main Display list box window
        this.listBox1.Items.Insert(0, aString);            
    }
    ...
}

But my problem is when I am in another class and I want to call 'TextToBox(myString);'. If I create another object reference of the MainForm, the code compiles fine but nothing will show up in the listBox. How do I do this? I cannot simply make TextToBox() static. I know I must create the object reference but I can't figure out how to reference the ORIGINAL MainForm, the one that was created in the Main method. Thanks in advance...

+1  A: 

I would just pass a delegate to the other class.

/* this runs (previous code was not guaranteed to run) */
class OtherClass
{
    public delegate void TextToBox(string s);

    TextToBox textToBox;
    int next = 0;

    public OtherClass(TextToBox ttb)
    {
        textToBox = ttb;
    }

    public void SendSomeText()
    {
        textToBox(next.ToString());
        next++;
    }
}

I'm assuming you'll be instantiating OtherClass from MainForm. Is this how you're calling "OtherClass"?

public partial class MainForm : Form
{
    OtherClass otherClass;

    public MainForm()
    {
        /* just two controls -- listBox1 and button1 */
        InitializeComponent();
        otherClass = new OtherClass(this.TextToBox);
    }

    public void TextToBox(string aString)
    {
        listBox1.Items.Add(aString);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        otherClass.SendSomeText();
    }
}

On a button click the next numeric value is added at the beginning of the ListBox. You'll have to post some of your code if you need further help.

Austin Salonen
Austin, thank you for the prompt reply. Unfortunately, the textToBox("Hello!");line generates a null reference exception. Would it help if I posted the complete code examples?Thanks again.
Andrew A
@Andrew A: Are you setting it like I do in the example constructor?
Austin Salonen
Austin, yes, I followed your example exactly. I tried the textToBox statement in another method and this time it compiled ok, but the string did not make it to the listBox...
Andrew A
@Andrew A: I added some code. Is this how you are doing it?
Austin Salonen
Austin, for simplicity sake I am doing it exactly as your example does, the only difference being SomeMethod() vs. SomePublicMethod(). In my OtherClass the method is names SomePublicMethod() per your example.
Andrew A
@Andrew A: See my updates.
Austin Salonen
Thank you Austin :)
Andrew A
A: 

alternatively you could use a singleton pattern, or static methods and make sure you include the class in a 'using' statement at the top of your program

Jason M
Jason, how do you use static methods in conjunction with non-static items such as listBox? Also, I tried adding the 'using ClassName;' at the top with the other using directives, but this added errors.
Andrew A
You should post some code to emphasize your point here because it reads like you're just rattling off buzzwords.
Austin Salonen
Singleton is a design pattern that is used to restrict instantiation of a class to a single instance or object. Its not "code". Its a way to do something. Static methods are methods that can be called without having to manually instantiate an instance of the class. Its also not directly "code".Design patterns aren't code, so look up the words before you demand code to emphasize simple points. I know you know this from reading some of your other answers to threads, though.
Jason M
A: 

This will work, but only when you have one instans of MainForm.

public class MainForm : Form
{
    public MainForm()
    {
        Instance = this;
    }

    public static MainForm Instance { get; private set; }

    // Function to output results to main Listbox window        
    public void TextToBox(string aString)
    {
        // Place messages in Main Display list box window
        this.listBox1.Items.Insert(0, aString);
    }

}
public class Other
{
    public void AddTextToListBox()
    {
        MainForm.Instance.TextToBox("Test");
    }
}

...Edit... Alternative:

class Program
{
    public static MainForm MainFormInstance;
    [STAThread]
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        MainFormInstance = new MainForm();
        Application.Run(MainFormInstance);
    }
}

public class Other
{
    public void AddTextToListBox()
    {
        Program.MainFormInstance.TextToBox("Test");
    }
}

Jens Granlund
Thank you Jens :)
Andrew A
You´re welcome.
Jens Granlund