-3

I want to access a textbox from another class.

Textbox1 should be accessed from class Log, using void AddLog.

So, anywhere in my application, I want to use Log.AddLog("...."), in order to add some text in the log window (textbox1), I wrote a function for that (it's AddLog):

public void AddLog(string s)
{
    new Form1().richTextBox1.Text += Environment.NewLine + s;
}

I set the modifier of textbox1 to public in order to call it from AddLog. When I call this function, nothing happens, nothing will be shown in textbox1....

I already searched, but nothing found that really helped me out.

Sayse
  • 42,633
  • 14
  • 77
  • 146
Marco Bader
  • 29
  • 1
  • 5
  • 2
    [new operator](https://msdn.microsoft.com/en-GB/library/fa0ab757.aspx) - "Used to **create** objects" – Sayse May 12 '15 at 14:51
  • In how far does that help? – Marco Bader May 12 '15 at 14:53
  • 1
    the new form does have its `richTextBox1` text correctly appended with the contents of string `s`, there are plenty of duplicate questions around about passing objects around between classes that I find it hard to think that nothing helped.. what did you search for and what did you try that didnt work? – Sayse May 12 '15 at 14:56
  • I did not understand what I found. Could you give me a solution? – Marco Bader May 12 '15 at 14:57
  • 2
    My solution would be the exact same as those that you already found, what have you tried so far that hasn't worked? – Sayse May 12 '15 at 14:58
  • Nothing, because I did not know how to implent that! – Marco Bader May 12 '15 at 15:02
  • 3
    I edited your question to remove my downvote, but please read [ask]. I recommend you try to solve your problem yourself and then come back with a more detailed question if you are still stuck (Hint: pass a reference) – Sayse May 12 '15 at 15:11
  • I hoped I could get help here.... – Marco Bader May 12 '15 at 15:14
  • 2
    The reason the first comment from @Sayse *is* helpful, is because your method creates a new instance of `Form1`. But as soon as the method exits, that instance is no longer accessible and is disposed. Your general idea is correct, but you need to understand *scope*. Two examples can be found [here](http://stackoverflow.com/a/29569629/3773066) and the first half of [this answer](http://stackoverflow.com/a/29294234/3773066). – OhBeWise May 12 '15 at 15:41

3 Answers3

1

The way you current code is structured, you are creating a new form each time you call AddLog. This is not the existing form that is visible, but rather a new one that isn't shown. You are adding the contents of variable s to the TextBox on this new form. The form is never shown, and since it's a local variable, it is eligible for garbage collection after this method is done running.

The Log class needs to have a reference to the existing form that is shown so it can add it to the correct instance. You could do something like:

public class Log
{
    private Form1 _form;
    public Log(Form1 formToUpdate)
    {
        _form = formToUpdate;
    }

    public void AddLog(string s)
    {
        _form.richTextBox1.Text += Environment.NewLine + s;
    }
}

But now you Log class is tied to a very specific form and it is directly messing around with a specific UI control on that form is doesn't own. This is very bad design.

Better ways to do this would to be for the Log class to raise an event which Form1 would subscribe to (assuming it makes sense for the form to have a reference to a Log instance). You could also create an interface for Form1 to implement and then have the constructor for Log take that interface type rather than a specific concrete type.

You need to learn about the basics of references, instance, constructors, etc.

Jeff B
  • 8,572
  • 17
  • 61
  • 140
  • Thanks, but how to call it? I can't call it Log.AddLog()! – Marco Bader May 12 '15 at 16:05
  • You haven't given us enough information. Who's going to create and own the instance of the `Log` class? You haven't told us how you want it to work or shown us code that would call the `AddLog` method. You should edit your question to provide sufficient information and clarify your question. – Jeff B May 12 '15 at 16:08
  • Okay. I thought I expressed it quite clearly, but here are some of my thoughts: Log.cs is a class. I want to use it as class to write to a logfile (done so far) and to a textbox in the main window (it's form1). Now I want to access Log.cs with Log.AddLog(s) from everywhere to display some messages, you know? – Marco Bader May 12 '15 at 16:13
  • You can't call the `AddLog` method off the class name `Log` since it is an instance method. You either need to create an instance (using `new`) and then pass that reference to everyone that needs it, or change it to be a static method (and probably the class to be static as well). If you don't understand the difference between instance and static method, you're going to have to do some research. These are basic C# concepts, it is absolutely imperative that you understand the basics before continuing. – Jeff B May 12 '15 at 16:26
  • You might also watch video [14: Understanding and Creating Classes](https://channel9.msdn.com/Series/C-Sharp-Fundamentals-Development-for-Absolute-Beginners/Understanding-and-Creating-Classes-14) and [15: More about Classes and Methods](https://channel9.msdn.com/Series/C-Sharp-Fundamentals-Development-for-Absolute-Beginners/More-about-Classes-and-Methods-15) found in the [C# Fundamentals: Development for Absolute Beginners series](https://channel9.msdn.com/Series/C-Sharp-Fundamentals-Development-for-Absolute-Beginners) over at Channel 9 on MSDN. Good luck! :) – Jeff B May 12 '15 at 16:36
1

Try this -

  public partial class Form1 : Form
  {
    Log log;
    public Form1()
    {
        InitializeComponent();
        log = new Log(richTextBox1);
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        log.AddLog(DateTime.Now.ToString());
    }

    private void button2_Click(object sender, EventArgs e)
    {
        log.AddLog();
    }
}

public class Log
{
    RichTextBox rtb;
    public Log(RichTextBox rtb)
    {
        this.rtb = rtb;
    }

    public void AddLog(string msg)
    {
        rtb.Text += msg + Environment.NewLine;
    }

    public void AddLog()
    {
        rtb.Text += DateTime.Now.ToString() + Environment.NewLine;
    }
}

This should do the trick. You need to pass the reference of the object which you want to modify.

Rohit
  • 1,520
  • 2
  • 17
  • 36
0
new Form1().richTextBox1.Text += Environment.NewLine + s;

Means that you create a new richTextBox, not current richTextBox1 in your Form.

It should be

public void AddLog(string s)
{
    this.richTextBox1.Text += Environment.NewLine + s;
}
anhtv13
  • 1,636
  • 4
  • 30
  • 51