views:

226

answers:

4

Hi,

How can I make a textbox in my winforms application that accepts new lines of text from anywhere in the application?

I have a main form that contains a textbox. I'd like to directly add text to the box from a method in another class.

Update

I tried this in my main form:

public void Output(String value)
    {
        if (txtOutput.Text.Length > 0)
        {
            txtOutput.AppendText(Environment.NewLine);
        }
        txtOutput.AppendText(value);
    }

But I can't call Output from the other class. I'm new to C#, so perhaps I'm missing something obvious.

Regards, Miel.

PS Yes, I know this is bad design, but for now this seems to be the best way to do what I want. The textbox would function like a console.

+3  A: 

You'll need to expose the Text property of the TextBox as a string property on your form. For example...

public string TextBoxText
{
    get { return textBoxName.Text; }
    set { textBoxName.Text = value; }
}

Edit

After reading the question edit, your problem is that you need a reference to a specific instance of the form whereever you're trying to execute that code. You can either pass around a reference (which is the better option), or you could use some smelly code and have a static property that refers to one instance of your form. Something like...

public partial class MyForm : Form
{
    private static MyForm instance;

    public static MyForm Instance
    {
        get { return instance; }
    }

    public MyForm() : base()
    {
        InitializeComponent();

        // ....

        instance = this;
    }
}

Using this approach, you could call MyForm.Instance.Output("test");

Adam Robinson
From the question the OP wants to add Lines, 1 at a time. So I'm guessing it's a MultiLine.
Henk Holterman
@Henk: And...? I'm not sure what you're getting at.
Adam Robinson
For this, smelly code is not an objection...
Miel
I would also add Exception in the constructor when before `instance = this;` instance is not null
Migol
A: 

It looks like your design is a little bit corrupted. You shouldn't let buisness logic mess with GUI controls. Why don't you try a return value and assigning it on the interface side?

Migol
Who said that business logic is doing the update? Why couldn't it be another UI control?
Adam Robinson
"anywhere in the application" implies for me that it would be also buisness logic.
Migol
+1  A: 

In order to decouple a bit more you could inverse the control a bit:

// interface for exposing append method
public interface IAppend
{
    void AppendText(string text);
}

// some class that can use the IAppend interface
public class SomeOtherClass
{
    private IAppend _appendTarget = null;

    public SomeOtherClass(IAppend appendTarget)
    {
        _appendTarget = appendTarget;
    }

    private void AppendText(string text)
    {
        if (_appendTarget != null)
        {
            _appendTarget.AppendText(text);
        }
    }

    public void MethodThatWillWantToAppendText()
    {
        // do some stuff
        this.AppendText("I will add this.");
    }

}

// implementation of IAppend in the form
void IAppend.AppendText(string text)
{
    textBox1.AppendText(text);
}
Fredrik Mörk
Seems over engineered
Adam Robinson
@Adam; that may be; it really depends on the complexity of the application in question. Is it a one-form, handfull of classes app, or a multiple assembly, loads of classes kind of app? In the first case I would find this over-engineered, in the latter I would find it suitable.
Fredrik Mörk
@Fredrik, Of course it's a matter of opinion, but in the latter case it seems like it would be more appropriate to have a more centralized singleton/static Logger approach rather than passing around loads of instances to the same interface. YMMV.
Adam Robinson
I like this solution as well, but my version of SomeOtherClass just contains some implementation of methods, and I'm not creating an instance anywhere, so I can't pass anything to it in the constructor.
Miel
A: 

This is a REALLY bad way of doing it, but just to make sure all the answers are out there...

In the VS designer, each form control has an item in the Properties window named Modifiers that defaults to Private. Changing this to one of the others settings, such as Internal or Public, will let you access it from outside the form.

I must stress that this is the worst way to do it.

R. Bemrose
...and that's why it shouldn't be suggested. You could also implement by way of having a global string variable and a timer on the form to poll it. That doesn't mean it's worth suggesting...
Adam Robinson