En los comentarios a la respuesta aceptada, Neeraj Gulia escribe:
Esto lleva a acoplamiento hermético de las formas Form1 y Form2, supongo que en su lugar se debe usar eventos personalizados para este tipo de escenarios.
El comentario es exactamente el correcto. La respuesta aceptada no está mal; para programas simples, y especialmente para personas que recién están aprendiendo programación e intentando que funcionen escenarios básicos, es un ejemplo muy útil de cómo un par de formularios puede interactuar.
Sin embargo, es cierto que el acoplamiento que causa el ejemplo puede y debe evitarse, y que en el ejemplo particular, un evento podría lograr lo mismo de forma desacoplada y de propósito general.
He aquí un ejemplo, utilizando el código de la respuesta aceptada como línea de base:
Form1.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Button1Click += (sender, e) => Lbl.Text = ((Form2)sender).Message;
frm.Show();
}
}
El código anterior crea una nueva instancia de Form2
, y luego antes de mostrarlo, agrega un controlador de eventos al evento Button1Click
de ese formulario.
Tenga en cuenta que la expresión (sender, e) => Lbl.Text = ((Form2)sender).Message
se convierte automáticamente por el compilador a un método que se ve algo similar a (pero definitivamente no exactamente) lo siguiente:
private void frm_Message(object sender, EventArgs e)
{
Lbl.Text = ((Form2)sender).Message;
}
En realidad, hay un montón de maneras/sintaxis para implementar y suscribe el controlador de eventos. Por ejemplo, usando un método anónimo como el anterior, realmente no necesita lanzar el parámetro sender
; en su lugar, puede usar la variable local frm
directamente: (sender, e) => Lbl.Text = frm.Message
.
Yendo en sentido contrario, no es necesario utilizar un método anónimo. De hecho, puede declarar un método regular como el generado por el compilador que muestro arriba, y luego suscribir ese método al evento: frm.Button1Click += frm_Message;
(donde por supuesto usó el nombre frm_Message
para el método, tal como en mi ejemplo anterior)
Independientemente de cómo lo hace, por supuesto que se necesitan para Form2
a aplicar en la práctica que Button1Click
evento. Eso es muy simple y hellip;
Form2.cs:
public partial class Form2 : Form
{
public event EventHandler Button1Click;
public string Message { get { return txtMessage.Text; } }
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
EventHandler handler = Button1Click;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
Además del evento, también han declarado una propiedad Message
que expone la propiedad Text
(y única la propiedad Text
, y sólo como lectura solo de hecho) del control txtMessage
. Esto permite que el suscriptor del evento obtenga el valor y haga lo que necesite con él.
Tenga en cuenta que todo lo que hace el evento es alertar al suscriptor de que se ha hecho clic en el botón. Depende del suscriptor decidir cómo interpretar o reaccionar ante ese evento (por ejemplo, recuperando el valor de la propiedad Message
y asignándola a algo).
Como alternativa, puede de hecho entregar el texto junto con el evento en sí, declarando una nueva EventArgs
sub-clase y el uso que para el evento en su lugar:
public class MessageEventArgs : EventArgs
{
public string Message { get; private set; }
public MessageEventArgs(string message)
{
Message = message;
}
}
public partial class Form2 : Form
{
public event EventHandler<MessageEventArgs> Button1Click;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
EventHandler handler = Button1Click;
if (handler != null)
{
handler(this, new MessageEventArgs(txtMessage.Text));
}
}
}
A continuación, el abonado puede simplemente recuperar el mensaje valor directamente desde el objeto de evento:
frm.Button1Click += (sender, e) => e.Message;
lo importante nota en todos t Las variaciones anteriores es que en ningún momento la clase Form2
necesita saber nada sobre Form1
. Tener Form1
saber acerca de Form2
es inevitable; después de todo, ese es el objeto que creará una nueva instancia de Form2
y la usará. Pero la relación puede ser asimétrica, con Form2
utilizable por cualquier objeto que necesite las características que ofrece. Al exponer la funcionalidad como un evento (y opcionalmente con una propiedad), se vuelve útil sin limitar su utilidad a la clase Form1
.
@Bob: ¿Está cerrando sus opciones de Formulario después de establecer las opciones y quiere que el formulario principal se abra con los valores de las opciones? – RKh
@Rohit: básicamente, sí. –