Reusing Forms

Greetings

I am converting a VB6 program containing multiple forms into a 2005.net VB program. In the old VB6 program I use a modal form and then I want to re-use the same form but but change some of the labels and make visible a control that was invisible the first time around. In the VB 6 version I was in, say, Form1 and executed the following code:

Unload Form1

Form1.Show 1

This re-did the Load event and I used a counter to customize the form in its second life.

Is there any way to do this simply in VS2005 VB



Answer this question

Reusing Forms

  • leclerc9

    Thanks again for the clarification.  I wonder if I could trouble you with the current state of my problem.  I have made some progress but...

    As suggested I created an instance of my form using the Dim/New statement.  I declared this in the module level code and made it Public. Let's say I called this instance GroupSee1.

    When I was in another form (say,  Form1) I invoked the showdialogue method on GroupSee1. It worked fine.  My data was displayed perfectly on GroupSee1.  Then my program wants to immediately display another set of data using the same form - in fact I might display up to 50 different sets of data in quick succession using the same form.  If effect I want to run through all the data in my data bank, one set at a time. So I tried this while still in GroupSee1:

    GroupSee1.close()                   (does this cause a problem by reverting back to the calling form )  

    GroupSee1.ShowDialogue()

    I get the error something like - cannot show dialogue that is already visible.  Set visible to false.

    OK, so I did this:

    GroupSee1.Visible=False

    GroupSee1.Close()

    GroupSee1.ShowDialogue()

    I get an error: Form that is already displayed modally cannot be displayed as a modal dialogue box.  Close the form before calling show.dialogue

    This mystifies me as I seem to have closed the form as shown above

    Then I declared another instance of my form called GroupSee2 and did the following:

    GroupSee1.Visible=False   (I suppose this was not necessary)

    GroupSee2.ShowDialogue

    This worked really well but to use this approach I would have to declare 50 such instances. One for each set of data  There must be a better way.  I have found a solution but it seems cumbersome.  I do this:

    GroupSee1.visible=False

    GroupSee1.visible=True

    This works fine except that if any data is missing from one of the later sets, the data from the previous group will still be sitting there from the previous invocation.  So the price I must pay is printing a null string to each label which has no data.  Not the end of the world but if there were just some way to blank out all the data from each form by calling in a "fresh" unmarked form my life would be easier and my code less cumbersome.  Is there a way

     Further work:

    The first set of code above does seem to cause a problem due to a reversion to the calling form (Form 1). At first in Form 1 I just had:

    GroupSee1.ShowDialogue

     

    Then in GroupSee1 I tried to execute(as explained above)

    GroupSee1.close()

    GroupSee1.ShowDialogue

    which generated the error shown above

    I then changed the code in Form1 to:

    GroupSee1.ShowDialogue

    GroupSee1.ShowDialogue

     

    when I did this I was able to see two iterations of this form.  So the Close() statement in GroupSee1 obviously sent the program back to Form1 and executed the second GroupSee. ShowDiaglogue statement.  Once again, it doesn't make sense to do this 50 times but is there a way around it   Oh yes, even this method does not avoid the problem of data from one form having its data left over onto the next form unless all the labels are cleared.

     

     

     

     

     

     

     

     


  • Joe M.199308

    This sounds like a useful tool. Thanks


  • JackyLi

    Application.OpenForms is a method/function in .NET that gives you a collection of opened forms in the application and you can access it by the index or form name

    http://msdn2.microsoft.com/en-us/library/system.windows.forms.application.openforms.aspx



  • pcompassion

    For the first time I am beginning to feel that I am not just hanging on by my fingernails but am starting to get a real sense of what handling forms in 2005 is all about. I thought that the Studio 2005 would simply allow me to use my VB6 program seamlessly. Talk about ignorance! I see now that I should do some serious reading before I dig myself into a real bog flailing around in a VB6 inspired fog.

    If I understand your text, creating a form is a bit like creating a user defined "type" in VB6 and previous versions of Basic. Then once the "type" is defined, a specific instance of this "type" must be declared for actual use. If this is true then I guess I can create one instance of a form, use it, close it and then later Dim another instance of the same form and the new instance will act like a virgin form with no history from the previous instance. This is what I want. (Does one actually use the "close" command to completely "unload" a modal form And what is the difference between the "hide" command and the "Form1.visible=false" command Does the "hide" command trigger the "ChangeVisible" event )

    I was getting confused because I wasn't aware of the legacy aspect - that's perhaps why I could call up forms directly as in VB6 but they weren't acting like they did in VB6. Messy. I am beginning to catch a glimpse of the power of the 2005 approach - I think a small light has started to glow.

    Thanks so much for taking the time to consider my question and compose such a clear and comprehensive response. Could you recommend a book I might study to get a solid grounding in the 2005 approach Maybe you should write one.


  • 12340987

    Easy one first - date was a typo - should have been data.

    The public statements are module level code in that they form part of a class but are not within a procedure. They define the access levels of each type. As written both forms are accessible from anywhere within the project.

    However, in this simple example, F should really be declared Private as there is no need to access it other than from Form1. I only declared it as Public because that is what you had done and I presumed you had a reason.

    As you state the data passed in this example is simply a string represenetation of the counter. In your case if you have multiple items to display then it may be worth defining a structure to hold them all and pass the structure rather than having multiple parameters.


  • vicky_dceian

    Thanks again Dave. Your example worked beautifully for me. Now I've just got to clean up some of the rough edges. Wish I had asked a few days ago!


  • Cyberjunkie

    Have a look at the following very simple example of what I think you are trying to achieve.

    This uses the constructor for the second form (Sub New) to display the date passed to it by the first form.

    When you click the button on the first form the second form is displayed but then no further code is run in the first form until the second form is closed. This could occur either by clicking the Close box or through code, e.g. Me.Close attached to a button.

    Once the second form is closed the loop in Form1 continues, creating a new instance of the second form and passing the next lot of data to its constructor.

    Form1 has a button

    Public Class Form1
    Public F As Form2
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    For Count As Integer = 1 To 10
    F = New Form2(Count.ToString)
    F.ShowDialog()
    Next
    End Sub
    End Class

    Form2 has a label and a constructor.

    Public Class Form2
    Public Sub New(ByVal Data As String)
    ' This call is required by the Windows Form Designer.
    InitializeComponent()
    ' Add any initialization after the InitializeComponent() call.
    Label1.Text = Data
    End Sub
    End Class


  • Ramibn1

    If you think of a form as a class with a user interface.

    You can create an instance of the form and not have it visible but when you instantiate an instance of a class you get an object.

    So

    dim x as new form1

    will create an object called x which is of type form1

    This will not be visible - its just in memory. If you want to make it visible you can use the show or showdialog method to make it visible as a non-modal or modal dialog. This is applying the method to the object.

    dim x as new form1
    x.show

    So this will show the form.

    If you want to show the form, hide it, reuse it later think of this as an object and as long as its still in scope and accessible you can call update the property on the form, call methods on it etc. The thing you have to be aware of is it not going out of scope.

    When you call it modally, then no further execution will take place until this dialog is closed. In which case this may not be what you want as if you close the form then it will no longer be accessible.

    VB6 has a feature called default instancing where it would create a default instance if you refered to the class name. So you didnt have to specifically create a object instance. This was because it was not a fully object oriented language, so this may have presented you with an illusion that you retained the same object after closing a modal dialog but in fact you were simply always using a default instance.

    In 2005, to aid VB6 users the default instancing feature was added back in and My.Application.OpenForms is part of this work. Rather than using default instancing I'd look at what you where trying to achieve and see if it is the best way to handle things.


  • Martin Cowen

    I think this is exactly what I need. A few Questions from a true neophyte:

    1. The Public statements (e.g. Public Class Form2 and Public F as Form 2) - are they module level code Where would this code be placed What do they accomplish

    2. In your second line is there a typo - should "date" be "data" I'm guessing that the data passed to the seond form is the "counter" reformatted as a string as shown in the brackets after

    F=NewForm2(

    I just want to make sure I follow.

    Thanks for your time. l think I'm all set now.


  • osamaT

    Thanks for your reply. I'm not well versed in the Studio 2005 context. I'm not sure what you mean by "Applications.OpenForms" but I will try to get a reference to it in Help.

    Thanks


  • kfindev

    Be careful with your terminology.

    VB6 has a concept of classes and this has not changed from VB6 to VB.Net. Classes are used to define objects.

    User Defined Types are sometimes referred to as structures, and although similar are slightly different. Doing a search on VB and value type and reference type will provide some details on the differences.

    That said all you need to do with forms is think of them as a class with a user interface. If you want to use objects in VB6 you need to instantiate instances to use them. This is really what you have to do with forms. Nothing magical, just in VB6 forms were treated differently from Classes in .NET they are treated in the same way by default.


  • pkv

    you can reuse a form either by declaring it globally then accessing it via that or create the form and then use Application.OpenForms to get the form you want via index.

    is this something you are after



  • tattoo

    I think you got it buddy! you are pretty much right on about the whole creating the instance of the form etc...

    yes, you can use Me.Close() to close the form and dispose of the object correctly. The hide command pretty much sets the visible property to false and show() method sets the visible property to true.



  • Reusing Forms