Question

i have a multi line text box that i would like to log messages to from other classes

however i am getting a infinite loop in class creation.

What is the correct way of update form controls from outside the form class?

namespace Program
{

    public partial class MainForm : Form
    {
        engine connEngine = new engine();

        public MainForm()
        {
            InitializeComponent();

        }

        private void Start_Click(object sender, EventArgs e)
        {
            msgLog("Connection Start Clicked");

            if (connEngine.StartConnection(txtIPAddress.Text, 8002) == false)
            {
                msgLog("Connection Start Failed"); 
            }
            else
            {
                msgLog("Connection Start Success");
            }

        }

        public void msgLog(string message)
        {
            txtMessageLog.AppendText(message + Environment.NewLine);
        }


        private void MainForm_Load(object sender, EventArgs e)
        {
            msgLog("Form Load Success");
        }

    }

    class engine
    {
        MainForm _mainForm = new MainForm();

        public bool StartConnection(string txtIPAddress, int p)
        {
            _mainForm.msgLog("StartConnection started");
            //do something
            return true;
        }
    }
}
Était-ce utile?

La solution

Piotr solution is good. However, I prefer to have an Action delegate instead in the class that wants to log. So the engine class remains independant of anything else coming from the MainForm, and everything stays loosely coupled.

public partial class MainForm : Form
{
    engine connEngine = new engine();

    public MainForm()
    {
        InitializeComponent();

        connEngine.log = s => { msgLog(s); };
    }

    private void Start_Click(object sender, EventArgs e)
    {
        msgLog("Connection Start Clicked");

        if (connEngine.StartConnection(txtIPAddress.Text, 8002) == false)
        {
            msgLog("Connection Start Failed"); 
        }
        else
        {
            msgLog("Connection Start Success");
        }

    }

    void msgLog(string message)
    {
        txtMessageLog.AppendText(message + Environment.NewLine);
    }


    private void MainForm_Load(object sender, EventArgs e)
    {
        msgLog("Form Load Success");
    }

}

class engine
{
    internal Action<string> log;

    public bool StartConnection(string txtIPAddress, int p)
    {
        log("StartConnection started");
        //do something
        return true;
    }
}

Autres conseils

Your problem is that you're creating an instance of the engine in the main form and an instance of the MainForm in the engine - this creates the loop. Instead of creating new instance of the MainForm in the engine, please consider passing it as a parameter to the engine's constructor. Something like this (not tested):

class engine
{
private MainForm _mainForm = null;

engine(MainForm formInstance)
{
   _mainForm = formInstance;
}

public bool StartConnection(string txtIPAddress, int p)
{
    _mainForm.msgLog("StartConnection started");
    //do something
    return true;
}
}

And you could use it like this:

    public partial class MainForm : Form
    {
       private engine connEngine = null;

       public MainForm()
       {
          InitializeComponent();

          connEngine = new engine(this);
       }

...

Excuse my formatting...

you have a bit of recursion here. MainForm instanciates an engine

public partial class MainForm : Form
{
    engine connEngine = new engine();

and engine instanciates a MainForm

class engine
{
    MainForm _mainForm = new MainForm();

What you end up with is an infinite cycle of instantiation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top