Monday, April 11, 2011

Persisting form data in Win forms applications.

In a C# winforms app what is the normal way to persist the data on form that is opened by another form? I'd planned on just keeping it all on the form object but when the form is closed it seems the that form object is disposed. meaning I loose all the data.

I could wrap the form up in another object which takes all the data off it but that seems like a lot of work.

Is there a way to just hide the form when it is closed rather than disposing of it?

From stackoverflow
  • 2 possibilities:

    1)catch the close event and just hide it. Create functions (to the hidden form) to get the input values using properties.

    private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        this.Visible = false;
        e.Cancel = true;
    }
    

    2)And what Moj tells: if you close the form after you created it, the form object will still be alive and can be accessed

    I favor 2) + the properties

    Omar Kooheji : so catching the close event and hiding it will override the normal behaviour and stop it from being disposed?
    PoweRoy : is you close it it will not be disposed, only when it goes out of scope
    Jacob Adams : However, I don't believe you can reshow it after it has been closed. I think you instead need to hide it
  • Use public properties.

    • Before closing, fill up these properties with corresponding values (ie. this._userName = txtUsername.Text)
    • Close the form
    • In the parent object of the form, you can still call dialog.Username to read the values.
  • On closing a form is not Disposed. Generally this is how the data is managed.

      Result res;
      using (MyForm form = new MyForm())
      {
          if(form.ShowDialog()== DialogResult.OK) 
          {
             // In Myform, after the data collection is done, you can set  DialogResult=DialogResult.Ok and close form using form.Close(); 
             res = form.Result; // expose forms data as result.                              
          }
      }
      UserResult(res);
    
    OregonGhost : You should be using using.
    Sung Meister : I second to using "using"
    OregonGhost : The Close() call is unnecessary, because ShowDialog() returns when the dialog has been closed. I removed the line in your post, but then felt dirty non-trivially editing someone else's post and revoked my change. Feel free to re-revoke it ;)
    nils_gate : Thanks, Learned and Done !
  • Accessing the child form's controls it is technically possible but not a good design. Here is how I do it:

    1) On Accept/Save button, you set the this.DialogResult to "OK", and get all the controls info. On the Close button or/and Closing event set this.DialogResult to "Cancel"

    2) If the data is mapped to an object (lets say "Customer") ... set the object properties. If not, just expose each control's data with a property, handling all the needing formating.

    3) Close the form using this.Close(); not dispose it.

    4) On your parent form check if dialog.ShowDialog() == DialogResult.OK and just then access the public properties you created in step 2... or if you load an object with the info just access that object in the form (by a Property also)

    5) THEN call the dialog.Dispose() method... either the user pressed OK or Cancel.

    Hope this helps you...

  • I recommend you to build a separate object contain the data. You can bind the form controls to its properties in a very simple way (designer supported, no code required). This keeps your data separated from the form.

    In case you don't know this document yet: How to: Create a Simple-Bound Control on a Windows Form

    Matthias

  • You could hide the form vs. disposing it but this is almost certainly not what you want. Forms take up resources in the process that will not be freed if you simply hide the form. They will only go away if you dispose of it. Keeping a bunch of Form instances around when they are not being used is just asking for a problem later down the road.

    What you likely want to do is pass back some result data from the Form after it's finished showing but before it's actually Closed. For example,

    MyDataObject data;
    using (var form = new SomeForm() ) {
      var dialogResult = form.ShowDialog(someWindow);
      data = form.InterestingData;
    }
    

0 comments:

Post a Comment