How to make child form change values in parent Form C#?

I have a C#record. There is a "street search" button that opens a Form Search child. When performing the search, it displays the result in the datagrid of that Form Child. I would like the cell_click event of the datagrid to complete the existing combobox in the parent form.

 12
Author: Maniero, 2014-01-30

7 answers

You can solve your problem by passing the parent reference to the child. I imagine you create an instance of this Form child inside the Form parent, so just pass the reference as follows:

Na Form pai

FormFilha container = new FormFilha(this);

Na Form daughter

private FormPai parent = null;
public FormFilha(FormPai _parent){
  this.parent = _parent;
}

From there it is possible to control the parent Form from within the child Form, including elements that are internal to FormPai, such as ComboBox for example, as long as the reference to that element have encapsulation level public.

 13
Author: Felipe Avelar, 2014-01-30 12:15:42

In this case you can pass the parent form as a parameter to the class, and through this parameter (in the case of the parent form object) you can interact with the parent form.

Form1 Code:

public Form1()
{
       InitializeComponent();
}
    //botao que ABRE o FORM B
private void button1_Click(object sender, EventArgs e)
{
    Form2 formB = new Form2(this); //this, significa que estou passando ESSA classe (instância dela) como param
    formB.Show();
}

Form2 Code:

public partial class Form2 : Form
{
    Form1 instanciaDoForm1; //objeto do tipo FORM 1, que será usado dentro da classe
    //inicializador do FORM
    public Form2(Form1 frm1) //recebo por parametro um objeto do tipo FORM1
    {
        InitializeComponent();
        instanciaDoForm1 = frm1; //atribuo a instancia recebida pelo construtor a minha variavel interna
        //associo o mesmo texto do tbxTextBoxFormA ao meu FORM B
        txtTextBoxFormB.Text = instanciaDoForm1.txtTextBoxFormA.Text.ToString();
    }
    //botao alterar
    private void button1_Click(object sender, EventArgs e)
    {
        //passo para a textbox do FORM A o mesmo texto que está na minha do FORM B
        instanciaDoForm1.txtTextBoxFormA.Text = txtTextBoxFormB.Text.ToString();
        instanciaDoForm1.txtTextBoxFormA.Refresh(); //recarrego ela
    }
}

So you can interact with the grid in the same way as you did with the textbox.

Article adapted from my friend Fernando Passaia http://www.linhadecodigo.com.br/artigo/1741/trocando-informacoes-entre-windows-forms-em-csharp.aspx

 7
Author: okevinlira, 2014-01-30 12:19:34

It is not good practice to delegate this responsibility to the child form. In general it would be the responsibility of the parent form (which contains the combobox) to modify the contents of this combo. You can create the child form as a data source (its job would be to list the items and tell which one was selected)

When displaying the form with a "ShowDialog" you get an enum with the result of that form (OK, cancel, etc) and you can use this flag to know if the user does not closed the screen without selecting anything. To get the selected item you can, through properties, expose the contents of the child form. This allows this child form to be used by any parent form.

public class Cidade
{
    public string Nome { get; set; }
}

public partial class FormPai : Form
{
    private void btnObterCidade_Click(object sender, EventArgs e)
    {
        var seletorCidade = new SeletorCidade();
        var resultadoSeletor = seletorCidade.ShowDialog();

        if (resultadoSeletor == DialogResult.OK)
        {
            var cidadeSelecionada = seletorCidade.CidadeSelecionada;
            comboCidade.SelectedItem = cidadeSelecionada;
        }
    }
}

public partial class SeletorCidade : Form
{
    public Cidade CidadeSelecionada { get; set; }

    private void btnOk_Click(object sender, EventArgs e)
    {
        this.DialogResult = DialogResult.OK;
    }

    private void btnCancelar_Click(object sender, EventArgs e)
    {
        this.DialogResult = DialogResult.Cancel;
    }
}
 4
Author: PhilHdt, 2014-01-30 12:33:30

A good way to do this in C# is to create an event in the child Form.
For example:

public event Action<String> EnderecoSelecionado;

When you create the child Form in the parent Form, you register for this event:

formFilho.EnderecoSelecionado += enderecoSelecionado_event;

When the user clicks on the child form grid, you check if there are functions registered in the event, if there are you run it:

if( EnderecoSelecionado != null ) {
    EnderecoSelecionado( o_endereco_selecionado );
}

This way the interface between parent and child will be very explicit and the same event can be reused in other parts of your application.
It it's a common C# idiom and I rarely regret using it.

 4
Author: Raul Almeida, 2014-01-30 12:37:23

The easiest way to do this is to create a publish variable in the Formfile and use ShowDialog() to call it with DialogResult, so when you click on the DataGrid vc calls this Code:

Statement in formfile

public int codigo { get; set; }

Click Command

codigo = valor;
DialogResult = DialogResult.OK;

Formfile call in formpai

Form2 formFilho = new Form2();
if (formFilho.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
     comboBox1.SelectedValue = formFilho.codigo;
}
 4
Author: user3258, 2014-01-30 12:41:16

For me it worked like this.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    // no meu caso quis pegar um Objeto do form filho.
    private Cliente cliente = null;
    public Cliente Cliente {
        get { return cliente; }
        set { cliente = value; }
    }

    private void Button1_Click(object sender, EventArgs e)
    {
        Form2 filho = new Form2();
        filho.Pai = this;
        filho.Show();
        Visible = false;
    }
}

Now in the child Form.

public partial class Form2 : Form
{
    public Form2
    {
        InitializeComponent();
    }

    private Form1 pai = null;
    public Form1 Pai {
        get { return pai; }
        set { pai = value }
    }

    private void Button1_click(object sender, EventArgs e)
    {
        Cliente cliente = new Cliente(long.parse(textBox1.Text));
        pai.Cliente = cliente;
        pai.Visible = true;
        this.Close();
    }
}

This way I call the child, pass the parent to an attribute inside the child and return an object to the parent form.

I tried other ways but in my Visual Studio 2017 these other ways were starting an empty Form that was not what I was starting.

And at the time of passing the child object to the parent, it was giving a null resort error(null).

I hope to have help.

 0
Author: João Victor Palmeira, 2019-03-24 02:18:52

You can do via events / delegates [which I think is more robust], return values with static variable in third class, passing the form via argument to change properties and, there is also a possibility that no one cites - I think it is the most complicated-you can access the information directly through the list of open Forms [Application.OpenForms], find it and change the property.

The downside is, if you rename the control or form, will have to change it also in the code, making maintenance more complicated.

I made an example project to make the understanding simpler:

  1. frmMain-parent Form
  2. frmSearch-search form
  3. in frmMain, I create a TextBox, named txtEx
  4. I call the frmSearch search form . Open the frmSearch, call the button click and on it try to change the Parent Control:

Example:

// Inicio
private void button1_Click(object sender, EventArgs e)
    {
        TextBox myText = (TextBox)Application.OpenForms["frmMain"].Controls["txtEx"];

        myText.Text = "10";

        this.Dispose();
    }  

Ready, when I return to the frmMain form, the value " 10 " is written in the TextBox. Be careful, if you miss the name of the form or the control, you will come across the launch of a System.NullReferenceException. Try this code.

Usage:

// Acesse: Application.OpenForms["NomeDoFormulário"]  e Controls["NomeDoControle"]
// Declara um controle TextBox, que servirá de ponteiro para o seu controle no formulário pai
// Faz a Conversão explícita de tipo de Controle (para poder alterar as propriedades) [(TextBox) ObjetoXYZ]
TextBox myText = (TextBox) Application.OpenForms["frmMain"].Controls["txtEx"];

// Altera de fato a propriedade
myText.Text = "XYZ";

// Encerra seu formulário Filho
this.Dispose();

Simply put:

(Application.OpenForms["frmMain"].Controls["txtEx"] as TextBox).Text = "Meu valor";
 0
Author: Guilherme Canaes, 2019-07-24 21:15:52