Ayush
Ayush

Reputation: 42450

Referencing Windows Form elements in other classes

I'm very new to Windows Form programming, and I'm coming across a problem.

I have a windows form, Form1, with a textbox: tbx_Log.

In another class in the same project, I want to write something to the log textbox, but I cannot reference tbx_Log in that class. How can I achieve this?

Upvotes: 5

Views: 19007

Answers (5)

o. nate
o. nate

Reputation: 384

I'd suggest that you create a method on the Form class that writes to the log textbox. Then you would pass that method as a delegate (callback) to your non-Form class. This gives you more flexibility down the road. For instance, if you wanted to call the same class from a different class, and you wanted to do something different with the logging information, such as writing it to a file, then you could just pass a different callback function.

Upvotes: 2

Mikael Svenson
Mikael Svenson

Reputation: 39695

You could make a public method on your form. And also make it thread safe in case it's called from a thread different than the UI thread.

How the other class accesses your method depends on how your app works and the relationship between the form class and your other class.

public void SetText(string text)
{
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns true.
    if (this.textBox1.InvokeRequired)
    {    
        SetTextCallback d = new SetTextCallback(SetText);
        this.Invoke(d, new object[] { text });
    }
    else
    {
        this.tbx_Log.Text = text;
    }
}

For a complete sample and explanation of thread-safe calls on winforms check MSDN, which also shows how to use BackgroundWorker in order to achieve thread-safety, which is the preferred way of doing it.

Upvotes: 0

jafesler
jafesler

Reputation: 117

You either need to make the textbox public (not recommended) or add a public method to your form class that will write a string to the textbox (better).

public class Form1
{
    protected Textbox tbx_Log;
    public void Log(string str)
    {
        tbx_Log.Text += str + Environment.NewLine;
    }
}

public class Program
{
    private void DoStuff()
    {
        Form1 myForm = new Form1();
        //Make form visible, etc...
        myForm.Log("Test Log");
    }
}

Upvotes: 2

jdehaan
jdehaan

Reputation: 19938

Accessing objects inside other class instances (objects) is bad style and violating data encapsulation. Add a method to Form1:

public void SetLogText(String text)
{
     tbx_Log.Text = text;
}

This way you can change the implementation of the method by using some other control or logging to a file later, without having to modify all the call sites. Always try to have the code outside the class not to have knowledge about what's inside. The class implementation shall be a "black box" for the outside code.

Upvotes: 4

Chris Taylor
Chris Taylor

Reputation: 53709

Rather than reference tbx_Log directly, I would suggest that at the very least you add a method to your Form which is responsible for performing the update. Then you can give your class a reference to the Form and have your class call the Forms logging function, which in turn adds the text to the text box.

I said at the very least, because you would probably want to define an interface and have your Form or later a more specific logging class that implements the interface and have your class interact with anything that implements the defined interface.

Upvotes: 1

Related Questions