views:

611

answers:

4

My TextBox won't update! I am using it as a Log to update what other things are doing...

Form 1 code:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Data.OleDb;
using System.Collections.Specialized;
using System.Text;

delegate void logAdd(string message);

namespace LCR_ShepherdStaffupdater_1._0
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent(); 
        }

        public void logAdd(string message)
        {
            this.Log.Items.Add(message); // Doesnt add to textbox

            this.Log.Items.Add("This won't update the textbox!!! Why?"); // Doesnt add to textbox
        }

        private void exitProgramToolStripMenuItem_Click(object sender, EventArgs e) 
        {
            Application.Exit(); 
        }
        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Form aboutBox = new AboutBox1(); 
            aboutBox.ShowDialog(); 
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void settingsToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            settingsForm.settings.ShowDialog();
        }

        private void synchronize_Click(object sender, EventArgs e)
        {
            this.Log.Items.Add("This WILL update the textbox. It is exactly the same as the other one..."); // This will add to the textbox
            DatabaseHandling.createDataSet();
        }

    }

    public class settingsForm 
    {
        public static Form settings = new Settings();
    }

}

My Logging Class code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LCR_ShepherdStaffupdater_1._0
{
    public class Logging
    {
        static Main mainClass = new Main();
        static logAdd logAddDelegate;

        public static void updateLog(string message)
        {
            logAddDelegate = mainClass.logAdd;
            logAddDelegate(message);
        }
    }
}

I am just completely stumped....does anyone know how I can fix the logAdd function so I can get my textbox log to finally update?

EDIT:

I finally got it to work, here was the fix:

Form1 Code

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Data.OleDb;
using System.Collections.Specialized;
using System.Text;

delegate void logAdd(string message);

namespace LCR_ShepherdStaffupdater_1._0
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent(); 
        }

        public void add(string message)
        {
            this.Log.Items.Add(message);
        }
        public void logAdd(string message)
        {
            Log.Invoke(new logAdd(add), new object[] { message });
        }

        private void exitProgramToolStripMenuItem_Click(object sender, EventArgs e) 
        {
            Application.Exit(); 
        }
        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Form aboutBox = new AboutBox1(); 
            aboutBox.ShowDialog(); 
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void settingsToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            settingsForm.settings.ShowDialog();
        }

        private void synchronize_Click(object sender, EventArgs e)
        {
            logAdd("this works");
        }

    }

    public class settingsForm 
    {
        public static Form settings = new Settings();
    }

}

Logging Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LCR_ShepherdStaffupdater_1._0
{
    public class Logging
    {
        static Main mainClass = new Main();
        static logAdd logAddDelegate;

        public static void updateLog(string message)
        {
            logAddDelegate = mainClass.logAdd;
            logAddDelegate(message);
        }
    }
}

Well...I can tell that is a really bad way to do it...but until I find a true fix as long as it works im happy. Thanks for the help guys!

A: 

I had a problem similar once before, it was solved by calling .Invalidate() on the text box after writing to it.

You could also check your message is actually getting to the textbox with:

debug.WriteLine( this.Log.Items( this.Log.Items.Count-1));

Hope that helps you.

Pondidum
Tried invalidate that didn't work...and i'm positive my message isnt getting to the textbox. Its because I am declaring a new Form. Just a design flaw...how to correct it? No clue -- yet.
OneShot
+1  A: 

What thread are you calling Logging.updateLog() from? If it's not the UI thread, I could see that the TextBox wouldn't get updated in that case. If you try calling logAdd() from synchronize_Click() (assuming that this is called from the UI thread based on the name), does it work then?

Andy
Yeah it works then. But how do I fix that?
OneShot
You can use Control.Invoke() to call a delegate on the thread that control was created on. This is required since WinForms controls must only be accessed on the thread on which they were created.
Andy
Thanks! I guess it is time to do some Googling cause I have no clue on how to use Control.Invoke().
OneShot
I figured it out...It may be hella sloppy...but I did.
OneShot
+4  A: 

From the code you posted your static Logger class is creating a new instance of the Main form. which is different than the one your running on the UI.

Overall this isn't a very good design pattern. write a comment if you want me to elaborate and give a sample.

bendewey
If there is a better way to do it, let me know! I know my design pattern sucks but googling "how to correct sucky programming design patterns" isn't easy as it may look. I don't know any better! :(
OneShot
The short answer is to create an interface for logging. the create a mainformlogging app that you spinup and assign it in your Program.cs file that would be aware of your MainForm (thru the consturctor maybe), something non-static. Then you can call that from a static class.
bendewey
Also, I'm not really sure why you need the delegate in this case. If your logger is aware of MainForm and MainForm has a public logAdd. just call mainForm.logAdd(message)
bendewey
http://cid-473151cb8afe66ba.skydrive.live.com/self.aspx/.Public/SimpleLoggingApplication.zip Just something I put together hope it helps
bendewey
+1  A: 

the synchronize_click is run on the instance of the main form that is running. The logadd function is run on a seperate main form that you create in the logging code. For this to work, you need to pass your existing main form into the log code so that it updates the text box you can see, not the extra text box you don't.

GWLlosa
How do I do that?
OneShot