4

I have done some research on this question before deciding to ask it. I just could not find anything that helped me.

I am writing an application in C# for the compact framework 2.0.

I need to take a data object instantiated on form1 and pass that object a form2. Work on the data object in form2 and then pass that data back to form1 so it can be saved.

I understand that a form is just an object an I also understand that objects are past by reference and not by value. I also understand the difference between the two types. I just cannot make it work for some reason.

What is the best, and cleanest, way in code to achieve this?

Kimtho6
  • 6,154
  • 9
  • 40
  • 56
Noble Bell
  • 87
  • 1
  • 2
  • 6

4 Answers4

5

What you need to do is create a second constructor to your second form that accepts an object as a parameter... for all I care, it could be the entire Form1 object instance, then you can get whatever you want from it. Preserve this object in your second form and modify it as needed there. Upon completion of your second form, your first form will have that data and you can do whatever "refreshing" once the second form closes.

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


}
DRapp
  • 47,638
  • 12
  • 72
  • 142
  • To add to this: from the first form, you would create an instance of the second form and then show it using `mySecondForm.ShowDialog()`. Since you're passing the parameter object by reference, you can change it however you like in the second form, and those changes will remain in the object when the ShowDialog() call returns. – MusiGenesis Feb 03 '11 at 15:21
  • @MusiGenesis .. Good point, I completely missed the CALLing to the second form as DIALOG based. Thanks for the catch. – DRapp Feb 03 '11 at 15:29
  • Wow. That simple. Your example and explanation were right on. Thank you. – Noble Bell Feb 03 '11 at 15:56
2

I've always liked the eventing model for this. This way your forms don't need to know about anyone else. You can setup an event like the following in some kind of EventHandler class that is used by both forms.

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

then your one form can call the SavingObject even handler and the other can subscribe to the SavingObjectEvent. When the first form triggers the event the second form will be notified do the processing that it needs and the object will then be available to the first form again after the manipulation.

Vadim
  • 17,897
  • 4
  • 38
  • 62
0

I've got an interesting solution for you, involving closure. In the constructor for Form2, require an Action<TypeOfThing> object, and whenever you need to return the data to Form1, call that Action and pass the data into it. For example:

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<TypeOfData> returnData;
    private TypeOfData data;

    public Form2(Action<TypeOfData> r)
    {
        returnData = r;
    }

    private void SomeFunction()
    {
        // Whenever it comes time to return the data you've collected
        returnData(data);
    }
}

I've used this implementation in the following circumstance: I had to request a password from the user, and I wanted to do so with a dialog box, so I designed my dialog box with a textbox where the user could type their password, and OK and Cancel buttons. On FormClosing, I'd return the string (their password) by calling the Action, and I would only ever use that Form as a dialog, so I could be sure the variable would be assigned to a string by the time the code continued in Form1. This way I didn't have to make a property for Password, which wouldn't have made sense because the password was only a temporarily necessary piece of data.

0

Something like this where the ObservableForm is a base class and contains the ChangeEvent for further flexability:

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

   }

}

dexter
  • 7,063
  • 9
  • 54
  • 71