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

Asked

Viewed 10,092 times

13

I have a register in C#. There is a "street search" button that opens a form search child. When executing the search, displays the result in the datagrid that form son. I would like the event cell_click of datagrid complete the combobox existing in the parent form.

7 answers

14


It is possible to solve your problem by passing the reference from father to son. I imagine you create an instance of this Form daughter inside the Form parent, therefore, it is sufficient to pass the reference as follows:

In the Form father

FormFilha container = new FormFilha(this);

In the 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 daughter Form, including elements that are internal to FormPai, like the ComboBox for example, provided that the reference for that element has an encapsulation level public.

  • when I type the this in new FormFilha(this), I get an error: "Keyword 'this' is not available in the Current context.".

8

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

Code of Form1:

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();
}

Code of Form2:

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
    }
}

Thus it is possible to interact with the grid in the same way as 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

5

A good way to do this in C# is to create a Form child event.
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 any functions registered in the event, if any you run it:

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

This way the interface between Father and Son will be very explicit and the same event can be reused in other parts of your application.
This is a common idiomatic expression of C# and a few times I was afraid to use it.

5

The easiest way to do this is to create a published variable in Formfilho and use Showdialog() to call it with Dialogresult, thus when clicking on the datagrid you call this code:

Statement on the formFile

public int codigo { get; set; }

Click command

codigo = valor;
DialogResult = DialogResult.OK;

Call of the formFilk in Formpai

Form2 formFilho = new Form2();
if (formFilho.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
     comboBox1.SelectedValue = formFilho.codigo;
}

5

It is not good practice to delegate this responsibility to the child form. In general it would be the responsibility of the parent form (containing 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 receive an Enum with the result of that form (OK, Cancel, etc.) and you can use this flag to know if the user has not closed the screen without selecting anything. To get the selected item you can, through properties, expose the content 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;
    }
}

0

It worked for me that way.

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 on Form Son.

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();
    }
}

in this way I call the son, pass the father to an attribute within the son and return an object to the parent form.

tried in other ways however 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 Object of the Son to the Father, was giving a null office error(null).

hope I’ve helped.

0

You can do via Events / delegates [which I find more robust], return values with static variable in third class, pass 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 negative point is, if you change the control name or form, you will have to change it also in the code, making maintenance more complicated.

I did an example project to make the understanding simpler:

  1. frmMain - Parent form
  2. frmSearch - form search
  3. In frmMain, I create a Textbox, named txtEx
  4. I call the form Search frmSearch . Open the frmSearch , call the button click and in it I 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 you return to the frmMain form, the value "10" is written in the Textbox. Be careful, if you miss the form or control name, you will come across the release of a System.NullReferenceException. Treat this code.

Use:

// 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();

Simplifying:

(Application.OpenForms["frmMain"].Controls["txtEx"] as TextBox).Text = "Meu valor";

Browser other questions tagged

You are not signed in. Login or sign up in order to post.