Copying a Form

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Aads
    New Member
    • Mar 2008
    • 48

    Copying a Form

    Hi there,

    Is there any method or a way to copy a form object to a variable?

    Let me explain this - We have a method called "Copy" for the Dataset class & you all must be knowing that there is a difference between the below two lines of code:
    Code:
                     DsTemp = Ds 
                     DsTemp = Ds.Copy()
    In the first line of code, any changes made to Ds will reflect in DsTemp. However, in the second line of code, any changes made to Ds will not reflect in DsTemp because we are only "copying" the contents & schema of Ds. Likewise is there a method or a work around to "copy" a Form object?

    Thanks in advance,
    Aads




    - please see the below code:

    Code:
     Dim Ds as Dataset
                     Ds.ReadXml("C:\MyXml.xml")
                     Dim DsTemp as Dataset = Ds.Copy()
    Last edited by Aads; Jan 8 '09, 07:17 AM. Reason: typo mistake
  • r035198x
    MVP
    • Sep 2006
    • 13225

    #2
    Controls don't seem to be Cloneable by default in .NET.
    Perhaps this article may help?

    Comment

    • Aads
      New Member
      • Mar 2008
      • 48

      #3
      Thanks for your help - that article did help me to explore about controls but the same doesn't apply for windows forms.

      Comment

      • Xennex
        New Member
        • Jan 2009
        • 7

        #4
        When I first used VB.NET the only way you could get a form was to define it first. For example if I had designed a form with the name "frmMenu" I would have had to create an instance of it first by DIMming it first. "dim myForm as New frmMenu" Then I would have to use myForm in all my further code. Now it seems you can use the classes like you could back in VB6 by just referencing them and letting the compiler create a new object automatically.. I believe if you dim a variable of type <your form class> with the New keyword like above, you should be able to create any number of objects of your form class, each with it's own set of properties that can be changed independent of any other object of that form class.

        Comment

        • vekipeki
          Recognized Expert New Member
          • Nov 2007
          • 229

          #5
          Why would you like to deep copy a Form object? You can create as many instances of a Form and display them simultaneously, but the actual data those forms are displaying doesn't have to be the same.

          For example:
          Code:
          MyForm f1 = new MyForm()
          f1.SomeData = myData.Clone(); // this will create a new copy
          f1.Show();
          
          MyForm f2 = new MyForm()
          f2.SomeData = myData.Clone(); // this will create a new copy
          f2.Show();
          
          // etc.

          What exactly are you trying to achieve, is there some data in your Form's properties that you would like to copy?

          Comment

          • Aads
            New Member
            • Mar 2008
            • 48

            #6
            Thanks for your reply - yes you are right; I've some data in my form which I want to preserve for subsequent uses. Let me explain you this with the help of below code snippet - please see the below code:

            Code:
             
            Dim _listOfForms As New List(Of Form) 'List to hold data of type Form.
            Dim _theFormChild As FormChild 'An instance of a child form
            
            Private Sub OpenChildForm()
               _theFormChild = New FormChild '--------> (1), See below NOTE after this code snippet
               _theFormChild.MdiParent = Me
               _theFormChild.Show()
            
               _listOfForms.Add(_theFormChild) 'Add it to the generic list.
            End Sub
            
            Private Sub OpenStoredChildForm()
               _listOfForms(0).Show() ' This doesn't open up a form. (quite obvious!)
            End Sub
            NOTE: As Soon as the control reaches the constructor of the child Form, lots of statements are executed. For ex:
            (a.) I instantiate around 8 classes which reads xml files of around 10 MB each. After it has read, it stores the data in the SortedList.
            (b.) Next I instantiate 5 modal forms which in turn again instantiates some other classes.
            (c.) Once the above tasks are done, I store (a.) & (b.) as properties of child Form i.e. as long as I've access to my child Form, I can happily access these properties as well.

            Now this process takes around 7 seconds to complete which happens everytime whenever the user hits a button in the form. All I want to do is whenever the user hits the button for the first time let this process go on (as it needs to if I want to store somewhere or even otherwise) but when he hits the button for the second time instead of initiating this process again from scratch I want to access this data where I would've stored (which is what is required).

            Is there a way where in I can store my child Form once it completes instantiation so that I can reuse the same Form whenever the user requires it thereby saving lot of time.

            Cheers,
            Aads

            Comment

            • Xennex
              New Member
              • Jan 2009
              • 7

              #7
              So you just need to have the child form available to use but not visible? If so you could simply hide the child form using its "Hide" method. All parts of the child form are still accessible until you unload the child form.

              Comment

              • Aads
                New Member
                • Mar 2008
                • 48

                #8
                Thanks for you quick reply. No I do not want the child form available just to use its properties. While this child Form is opened, if the user opens another copy of this form (without closing the one which is already opened), a new form opens going through all the process which I mentioned in the previous post thereby taking lot of time & this is what I do not want which is time consuming. All I want is that when the user opens the form subsequent times, it should open instantaneously with all the properties set (some how).


                Cheers,
                Aads

                Comment

                • vekipeki
                  Recognized Expert New Member
                  • Nov 2007
                  • 229

                  #9
                  Instead of cloning the Form, consider cloning the Form's data. For example, you already have a ChildForm constructor like this:

                  Code:
                  public ChildForm()
                  {
                      InitializeComponent();
                      // do lots of xml work
                  }
                  and then you have a ChildForm property with large quantities of data:

                  Code:
                  private MyDataClass LargeData
                  {
                      get { return this.largeData; }
                      set { this.largeData = value; }
                  }
                  So, all that you need to do is add a parameterized constructor which accepts MyDataClass, or event ChildForm as input:

                  Code:
                  public ChildForm(ChildForm otherCopy)
                  {
                      InitializeComponent();
                      // instead of doing xml work, just copy the data
                      // (note that we can access private properties in
                      // otherCopy instance)
                      this.LargeData = otherCopy.LargeData;
                  
                      // or this.largeData = otherCopy.LargeData.Copy(); if you want a deep copy
                  }
                  Then you can create a form by calling this constructor:
                  Code:
                  ChildForm c = new ChildForm(someOtherForm);
                  c.MdiParent = this;
                  c.Show();
                  I just realized you're using VB.NET -- sorry. You should probably get the general idea.

                  Also, it is up to you to decide whether you want to Clone the data (make a separate deep memory copy), or just pass the reference to the same instance.

                  Comment

                  • Aads
                    New Member
                    • Mar 2008
                    • 48

                    #10
                    Hey thanks for your reply. I tried the technique suggested by you (storing xml data in properties & accessing it when required) - it worked absolutely fine. But could you please tell me what exactly "deep copy" means?

                    Cheers,
                    Aads

                    Comment

                    • vekipeki
                      Recognized Expert New Member
                      • Nov 2007
                      • 229

                      #11
                      You can try googling for "deep copy vs shallow copy". You can also look for articles on "reference types vs value types", it will help you understand what's going on with your data.

                      The difference is:
                      • If you want to copy the entire data, so that changes to the copy are not reflected in your original instance, then you want a deep copy. This means .NET will need to allocate as much memory as for the original object, and all objects which are pointer by your object will also be copied.
                      • If you are just displaying your data, or you don't care if you are working with the same instance of you data in two places, then you can use a shallow copy, or you can simply use a reference to your first object.


                      No copying is done if you are using a reference - you only have a single object in memory. If you are using a shallow copy, then you are making a new object, but other objects which are pointed by your object are not copied, so changes to these objects will again reflect in your original object.

                      Here is an example. Consider you have a class such as this:
                      Code:
                      class MyData
                      {
                          private List<int> _list = new List<int>();
                          public IList<int> List
                          {
                              get { return _list; }
                          }
                      
                          public MyData GetShallowCopy()
                          {
                              return this.MemberwiseClone() as MyData;
                          }
                      
                          public MyData GetDeepCopy()
                          {
                              MyData deepCopy = new MyData();
                              foreach (int item in this.List)
                                  deepCopy.List.Add(item);
                              return deepCopy;
                          }
                      
                          public override string ToString()
                          {
                              StringBuilder sb = new StringBuilder();
                              foreach (int item in this.List)
                              {
                                  sb.Append(item);
                                  sb.Append(", ");
                              }
                              if (sb.Length > 2)
                              {
                                  sb.Length -= 2;
                              }
                      
                              return sb.ToString();
                          }
                      }
                      MyData is a class which contains a List of ints. It also has two methods, "GetShallowCopy " and "GetDeepCop y". The "ToString" method is overridden to simplify printing the object to the Console.

                      Note the difference between GetShallowCopy and GetDeepCopy.

                      Now, if you were to use this class in your program, you would do something like this:
                      Code:
                      static void Main(string[] args)
                      { 
                          MyData data = new MyData();
                          data.List.Add(1);
                          Console.WriteLine(String.Format("Original array: {0}",data.ToString()));
                      
                          // This will just create a reference.
                          // reference points to the same object as data, and therefore
                          // reference.List points to the same object as data.List.
                          MyData reference = data;
                          reference.List.Add(2);
                          Console.WriteLine(String.Format("Original array: {0}\t Reference:\t{1}", data.ToString(), reference.ToString()));
                      
                          // This will create a shallow copy.
                          // shallowCopy points to a new object, but
                          // shallowCopy.List still points to the same object as data.List.
                          MyData shallowCopy = data.GetShallowCopy();
                          shallowCopy.List.Add(3);
                          Console.WriteLine(String.Format("Original array: {0}\t Shallow copy: \t{1}", data.ToString(), shallowCopy.ToString()));
                      
                          // This will create a deep copy.
                          // deepCopy points to a new object,
                          // and deepCopy.List points to a new object.
                          MyData deepCopy = data.GetDeepCopy();
                          deepCopy.List.Add(4);
                          Console.WriteLine(String.Format("Original array: {0}\t Deep copy: \t{1}", data.ToString(), deepCopy.ToString()));
                      
                          Console.ReadLine();
                      }
                      If you try to run this program, you will notice that any changes to the data in the reference or shallow copy of the original object, are reflected in the original object also. Shallow copy is a new object, but it still points to the same List as the original object. Only the deep copy contains a truly separate list in memory, which can be updated independently.

                      Comment

                      • Aads
                        New Member
                        • Mar 2008
                        • 48

                        #12
                        Many thanks for spending your time in explaining the differences between Shallow copy & Deep copy - I appreciate it. No wonder, I did not have to google after having read your reply. Cheers buddy that was really helpful.


                        Cheers,
                        Aads

                        Comment

                        Working...