¿Cómo pasa un objeto de form1 a form2 y vuelve a form1?

Hice algunas investigaciones sobre esta pregunta antes de decidir preguntarla. Simplemente no pude encontrar nada que me ayudara.

Estoy escribiendo una aplicación en C # para el marco compacto 2.0.

Necesito tomar un objeto de datos instanciado en form1 y pasar ese objeto a form2. Trabaja en el objeto de datos en form2 y luego pasa esos datos a form1 para que pueda guardarse.

Entiendo que una forma es solo un objeto y también entiendo que los objetos son pasados ​​por referencia y no por valor. También entiendo la diferencia entre los dos tipos. Simplemente no puedo hacer que funcione por alguna razón.

¿Cuál es la mejor y más limpia forma de código para lograr esto?

Lo que tienes que hacer es crear un segundo constructor para tu segunda forma que acepte un objeto como parámetro … por lo que a mí respecta, podría ser toda la instancia del objeto Form1, entonces puedes obtener lo que quieras de él. Preserve este objeto en su segunda forma y modifíquelo según sea necesario allí. Al completar su segundo formulario, su primer formulario tendrá esa información y podrá hacer lo que sea “refrescante” una vez que se cierre el segundo formulario.

public partial class YourSecondForm : Form { object PreserveFromFirstForm; public YourSecondForm() { ... its default Constructor... } public YourSecondForm( object ParmFromFirstForm ) : this() { this.PreserveFromFirstForm = ParmFromFirstForm; } private void YourSecondFormMethodToManipulate() { // you would obviously have to type-cast the object as needed // but could manipulate whatever you needed for the duration of the second form. this.PreserveFromFirstForm.Whatever = "something"; } } 

Siempre me ha gustado el modelo de eventos para esto. De esta forma, sus formularios no necesitan saber de nadie más. Puede configurar un evento como el siguiente en algún tipo de clase EventHandler que sea utilizada por ambos formularios.

 public delegate void SavingObjectHandler(MyObject obj); public event SavingObjectHandler SavingObjectEvent; public void SavingObject(MyObject obj) { if (SavingObjectEvent != null) SavingObjectEvent(obj); } 

entonces su única forma puede llamar al manejador de ahorro SavingObject y la otra puede suscribirse al evento SavingObjectEvent. Cuando la primera forma desencadena el evento, se notificará la segunda forma, haga el procesamiento que necesita y el objeto estará disponible para la primera forma nuevamente después de la manipulación.

Algo como esto donde el ObservableForm es una clase base y contiene el ChangeEvent para mayor flexibilidad:

  public class FormMain : Form { private ObServableForm childForm = null; public FormMain () { this.childForm = new ObservableFormConcreateA(this); this.childForm.ChangeEvent += (sender, e) => Application.DoEvents(); } public void Present() { this.childForm.Show(); } } public class ObservableFormConcreateA ObServableForm { private Form workItemForm = null; private delegate void FormChangedHandler(object source, EventArgs args); //ToDo: this should go in the superclass public event FormChangedHandler ChangeEvent; public FormChild(ObServableFormworkItem) { this.workItemForm = workItem; } public void OnUserActionHandler(object sender, EventArgs e) { this.formItemForm.Property = this.txtBoxWhateverValue.Text; if(ChangeEvent != null) ChangeEvent(this, //create your args to specify which control/data changes); } 

}

Tengo una solución interesante para ti, que implica el cierre. En el constructor para Form2, requiera un objeto Action , y siempre que necesite devolver los datos a Form1, llame a esa Acción y pase los datos en ella. Por ejemplo:

 class Form1 : Form { private void SomeFunction() { TypeOfData data; Form2 form2 = new Form2((d) => { data = d; }); form2.ShowDialog() // or whatever you do with form2 // After you've definitely got your data object from Form2 DoStuff(data); } } class Form2 : Form { private Action returnData; private TypeOfData data; public Form2(Action r) { returnData = r; } private void SomeFunction() { // Whenever it comes time to return the data you've collected returnData(data); } } 

Utilicé esta implementación en las siguientes circunstancias: tuve que solicitar una contraseña al usuario, y quería hacerlo con un cuadro de diálogo, así que diseñé mi cuadro de diálogo con un cuadro de texto donde el usuario podía escribir su contraseña, y Botones OK y Cancelar. En FormClosing, devolvía la cadena (su contraseña) llamando a Action, y solo usaba ese formulario como diálogo, por lo que podía estar seguro de que la variable se asignaría a una cadena para cuando el código continuara en Formulario 1. De esta forma, no tuve que hacer una propiedad para la Contraseña, lo que no tendría sentido porque la contraseña era solo una pieza de datos temporalmente necesaria.