简体   繁体   中英

Working with win forms

I have 2 win forms..Form A and B, form B is let's say child and A is parent...

Form B is sending some data to A, but i have duplicate process with form A when i close form B...a second form A opens up...

This is the code that I put in form B...but the problem is that the value from form B is not "going" to form A...with this code only form A opens up, there is no duplicate process and B closes up, but no data comes from B to A...

This is the code:

private void button1_Click(object sender, EventArgs e)
{
    //Index of the row which is currently selected.
    int myIndex = dataGridView1.CurrentRow.Index;       
    DataGridViewRow row = this.dataGridView1.Rows[myIndex];
    brdok = row.Cells["Broj_dokumenta"].Value.ToString();
    FormCollection fc = Application.OpenForms;
    bool FormFound = false;

    foreach (Form frm in fc)
    {
        if (frm.Name == "Main")
        {
            //Open form A
            Main f = new Main();
            f.textRadniNalog.AppendText(brdok);
            f.Focus();

            FormFound = true;
        }
    }

    if (FormFound == false)
    {
        Main f = new Main();
        f.Show();
    }

    //close form B 
    this.Close();
}

The other answer explains how you can keep your current basic architecture, except without the specific bug. That said, Marko's comment is a better answer. Here's what that would look like:

partial class Main : Form
{
    private void button1_Click(object sender, EventArgs e)
    {
        // Add whatever other initialization is needed here, of course
        new FormB(this).Show();
    }
}

partial class FormB : Form
{
    private Main _main;

    public FormB(Main main)
    {
        _main = main;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        //Index of the row which is currently selected.
        int myIndex = dataGridView1.CurrentRow.Index;       
        DataGridViewRow row = this.dataGridView1.Rows[myIndex];
        brdok = row.Cells["Broj_dokumenta"].Value.ToString();
        _main.textRadniNalog.AppendText(brdok);
        _main.Focus();
        //close form B 
        this.Close();
    }
}

If it's actually possible for the Main form to be closed while FormB is open (something you can prevent by showing FormB using the ShowDialog() method instead of the Show() method), then you can add logic to account for that:

partial class FormB : Form
{
    private Main _main;

    public FormB(Main main)
    {
        _main = main;

        if (_main != null)
        {
            _main.FormClosed += (sender, e) => _main = null;
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (_main != null)
        {
            //Index of the row which is currently selected.
            int myIndex = dataGridView1.CurrentRow.Index;       
            DataGridViewRow row = this.dataGridView1.Rows[myIndex];
            brdok = row.Cells["Broj_dokumenta"].Value.ToString();
            _main.textRadniNalog.AppendText(brdok);
            _main.Focus();
        }
        else
        {
            new Main().Show();
        }

        //close form B 
        this.Close();
    }
}

If needed, you can similarly handle the scenario where the Main form could be opened after FormB is shown; the code that does that would of course need to know about the FormB instance, and would pass the new Main form instance reference to it when it shows the form. In that case — where forms rely on each other but come and go on some arbitrary mechanism — it would be best, rather than having each individual form have to know what other form(s) have to react to them, for you to have some top-level controller object that deals with all of the interactions, including being the go-between for events and state changes in different windows.

looks like you are creating a new instance even when the form is found

if (frm.Name == "Main")
{
  //Open form A
  Main f = new Main();

please try changing it to

if (frm is Main)
{
        Main f = frm as Main;
        f.textRadniNalog.AppendText(brdok);
        f.Focus();

or

var mainFrm=fc.OfType<Main>().FirstOrDefault();

if (mainFrm != null)
{
    mainFrm.textRadniNalog.AppendText(brdok);
    mainFrm.Focus();
}
else
{
    Main f = new Main();
    f.Show();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM