Home > Back-end >  C# Excecute method in original Form from another Form
C# Excecute method in original Form from another Form

Time:01-08

I have a simple question for some of you.

I have two forms which contain two methods:

FORM 2: Which will take input from textbox and run a method from FORM1

public partial class Form2 : Form
    {
        Form1 mainForm = new Form1();
        public Form2()
        {
            InitializeComponent();
            //Form2_Load();
                        
        }


        private void txtCmdOutput_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                if (e.KeyCode == Keys.Enter)
                {
                    mainForm.outPutMessage(txtCmdOutput.Text.Length, 2, txtCmdOutput.Text.ToString());
                    txtCmdOutput.Text = "";

                }
            }
            catch (Exception err)
            {

            }
        }

FORM 1: Which will contain the method that will excecute using the inputs from FORM 2

public void outPutMessage(int bufferSize1, int messageID1, string message1)
        {
            NetworkStream networkstream = client.GetStream();


            int bufferSize = bufferSize1;
            var message = message1;

            int messageID = messageID1;

            string headerStr = "len:"   message.Length.ToString()   "\r\nMsgId:"   messageID;

            byte[] headerLength = BitConverter.GetBytes(headerStr.Length);

            networkstream.Write(headerLength, 0, 4);

            networkstream.Write(Encoding.ASCII.GetBytes(headerStr), 0, headerStr.Length);


            int bytesSent = 0;
            int bytesLeft = message.Length;
            byte[] encodedMessage = Encoding.ASCII.GetBytes(message);

            while (bytesLeft > 0)
            {
                int curDataSize = Math.Min(bufferSize, bytesLeft);
                networkstream.Write(encodedMessage, bytesSent, curDataSize);

                bytesSent  = curDataSize;
                bytesLeft -= curDataSize;
            }
        }

My question is, is it possible to call the

outPutMessage(txtCmdOutput.Text.Length, 2, txtCmdOutput.Text.ToString());

from FORM 2(by taking the input from the textbox), but actually run the method in its original form (FORM 1)? as there is where all the other variables are contained.

What I attempted to do is indicate Form1 mainForm = new Form1(); and call the method, but it seems to then run the method in FORM 2.

UPDATE:

This is how I create FORM 2 from FORM 1:

private void button_Click1(object sender, EventArgs e)
        {
            Button selected = sender as Button;
            openClientForm(new Form2());
            outPutMessage("".Length, 4, ""); 
        }

private Form2 activeForm = null;
        private void openClientForm(Form2 clientForm)
        {
            if (activeForm != null)
                activeForm.Close();
            activeForm = clientForm;
            clientForm.TopLevel = false;
            clientForm.FormBorderStyle = FormBorderStyle.None;
            clientForm.Dock = DockStyle.Fill;
            panelClientForm.Controls.Add(clientForm);
            panelClientForm.Tag = clientForm;
            clientForm.BringToFront();
            clientForm.Show();
        }

THanks in advance.

CodePudding user response:

As per @jmcilhinney setup an event in the child form, here in a Button Click event push information to listeners which means the child form does not know anything about the calling form.

This would be your child form

namespace PassStringFromChildToParentForm
{
    public partial class ChildForm : Form
    {
        public delegate void OnPassData(int bufferSize1, int messageID1, string message1);
        public event OnPassData PassData;

        public ChildForm()
        {
            InitializeComponent();
        }

        private void PassDataButton_Click(object sender, EventArgs e)
        {
            PassData?.Invoke(textBox1.Text.Length,2, textBox2.Text);
        }
    }
}

The main form

namespace PassStringFromChildToParentForm
{
    public partial class MainForm : Form
    {

        public MainForm()
        {
            InitializeComponent();
        }

        private void ShowChildForm_Click(object sender, EventArgs e)
        {
            ChildForm childForm = new ChildForm();
            childForm.PassData  = PassData;
            childForm.Show(this);
            
        }
        private void PassData(int bufferSize1, int messageID1, string message1)
        {
            // perform work
        }
    }
}

CodePudding user response:

This may help you. If you change your Program.cs file to save your mainForm as a public variable like this:

static class Program
{
    public static Form1 mainForm;

    [STAThread]
    static void Main()
    {

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(mainForm = new Form1());
    }
}

Then when you need to reference the mainForm in your appliation like from Form2 or anywhere else you can use the following:

Program.mainForm.outPutMessage();

This will allow you to access anything from the mainForm as long as its public.

Or another approach is to pass a reference of Form1 to Form2 when you create it so that you can reference it later as I suggested in comments.

private void button_Click1(object sender, EventArgs e)
{
    Button selected = sender as Button;
    // if run from Form1 then 'this' is form1
    openClientForm(new Form2(this)); 
    outPutMessage("".Length, 4, ""); 
}

Then change Form2.cs constructor to save it:

public partial class Form2 : Form
{
    private Form1 mainForm;
    public Form2(Form1 mForm)
    {
        InitializeComponent();
        this.mainForm = mForm;          
    }

Then from that point on you can just use:

mainForm.outPutMessage();

The problem with this approach is that anytime you create a Form2 you need to pass it Form1. Or you can pass it another form, or null, but that may cause issues depending on your code.

There are many other solutions for what you are trying to accomplish, but I believe these are likely what you are looking for in your current scenerio without refactoring everything.

  • Related