Note: I know the question is old, but I believe the answer can help other users.
Introducing
A solution to this question would be to use Events, events allow classes or objects to notify other classes or objects that a certain action has been performed, allowing those who signed these events to perform some task related to it.
We use events often, a basic example would be the event Click
of the component Button
, which enables us to do something when a button is clicked.
Codes
I set up a scenario like the one you reported, I set up the name of Form
main as frmPrincipal
:
using System;
using System.Windows.Forms;
namespace App.Teste
{
public partial class frmPrincipal : Form
{
public frmPrincipal()
{
InitializeComponent();
}
private void btnCadastrarConta_Click(object sender, EventArgs e)
{
stcMenuPrincipal.Panel2.Controls.Clear();
frmCadastroConta formulario = new frmCadastroConta();
formulario.TopLevel = false;
formulario.AutoScroll = true;
formulario.NextForm += new frmCadastroConta.NextFormEventHandler(formulario_NextForm); // assina o evento
stcMenuPrincipal.Panel2.Controls.Add(formulario);
formulario.Show();
}
// método que irá tratar o evento
private void formulario_NextForm(object source, string name)
{
((Form)source).Close();
if (name == "frmInformacoesAdicionais")
{
frmInformacoesAdicionais formulario = new frmInformacoesAdicionais();
formulario.TopLevel = false;
formulario.AutoScroll = true;
stcMenuPrincipal.Panel2.Controls.Add(formulario);
formulario.Show();
}
}
}
}
In the frmCadastroConta
, I created the button btnInformacoesAdicionais
that will trigger the event to load the frmInformacoesAdicionais
:
using System.Windows.Forms;
namespace App.Teste
{
public partial class frmCadastroConta : Form
{
public delegate void NextFormEventHandler(object source, string name);
public event NextFormEventHandler NextForm;
public frmCadastroConta()
{
InitializeComponent();
}
private void btnInformacoesAdicionais_Click(object sender, System.EventArgs e)
{
OnNextForm("frmInformacoesAdicionais");
}
public virtual void OnNextForm(string name)
{
// verifica se o evento possui algum assinante
if (NextForm != null)
NextForm(this, name);
}
}
}
The frmInformacoesAdicionais
has nothing special, just created a Form
with a Label
to identify him.
Explanations
The Form
that will generate the event is the frmCadastroConta
, and what will receive (sign) the event is the frmPrincipal
, i.e., the frmCadastroConta
will notify the frmPrincipal
through the event NextForm
that a new Form
must be loaded.
These lines below make it possible to use events:
public delegate void NextFormEventHandler(object source, string name);
public event NextFormEventHandler NextForm;
...
public virtual void OnNextForm(string name)
{
// verifica se o evento possui algum assinante
if (NextForm != null)
NextForm(this, name);
}
Declared a Delegate, the event itself and a method to call the event.
Observing: in the statement of delegate
you can inform the parameters you find necessary, I added the source
to identify which object generated the event and the name
to identify which Form
carry.
Observation 2: the name of the delegate, the event and the event method (consider using the prefix On
as a good practice for this case) it is you who choose.
Done this you must sign the event on frmPrincipal
as the line shows:
formulario.NextForm += new frmCadastroConta.NextFormEventHandler(formulario_NextForm);
Observing: you can define the name you think best for your method, not forgetting to declare it with the same parameters of delegate
.
The method formulario_NextForm
will treat the generated event, which in this case will close the Form
who uploaded the event and uploaded the Form
passed by the parameter name
.
Completion
The use of Events in this case, it leaves its code cleaner and organized, being free of "gambiarras".
References
Communication between Forms in . NET
C# - Events
How to Perform and Cancel the Event Subscription (Programming Guide in C#)
Have you ever tried the same procedure you did to display the
frmCadastroConta
to display thefrmInformacoesAdicionais
?– Felipe Avelar
I even tried, man, it didn’t work. However, I did a gambiarra. I put the split of my main menu as public and adapted the code. You would have another way?
– cumpadi