Paul,
Try chainging this line:
Private Function ShowForm(ByVal FormToShow As Form)
To this:
Private Function ShowForm(ByRef FormToShow As Form)
Passing FormToShow "ByRef" -- by reference instead of by value.
Linda - 01 Apr 2005 15:40 GMT
Oh, I should have explained this more: even if you know why this would
work better, somone googling for the answer later may not.
When you pass your form "ByVal", you are not actually passing your
form-- you are making a *copy* of the form, and passing that. The
system doesn't recognize the copy, hence you get the error message that
you reported.
Using "ByRef" passes the *address* of your form to the subroutine,
rather than a copy. So the action is preformed on the origional form,
as you wish, rather than on a "copy" that's just haning around
disconnected from anything.
Hope this helps!
AdamRobinson - 02 Apr 2005 19:11 GMT
> Oh, I should have explained this more: even if you know why this would
> work better, somone googling for the answer later may not.
[quoted text clipped - 10 lines]
>
> Hope this helps!
That is actually incorrect. The discrepancy comes in how you think you
are referencing your form.
Object references (which is basically everything except numeric types
and other certain intrinsic types, NOT including strings) are variables
that represent pointers to locations in memory. When you have a
variable defined as, say, a form (or any other object type), that
variable doesn't represent the object itself, but rather that pointer
that points to the location in memory of the object. That is what your
variable is.
Now what does this mean? When you pass an object reference to a
function ByVal, then EVERYTHING PERFORMED on that object reference
EXCEPT FOR ASSIGNMENTS is performed on the actual object. The only
difference between ByVal and ByRef is the behavior of assignments.
ByVal parameters do not affect the variable in the calling method,
ByRef parameters do.
That clear as mud?
As for the original question, this isn't really possible without diving
into reflection (you'd have to pass the type in using the GetType()
keyword, then find the declaring assembly and instantiate it, which is
a costly operation), and IMHO this is a bit of a violation of good
programming practices.
Now, that said, this sort of thing will be a little easier and less
costly in VS2005 using generics. However, you are writing this function
simply because you do not want to instantiate a form?
Also, you are simply catching EVERY exception, then reattempting the
same operation, which is bad. You do not know that the exception you
caught was a NullReferenceException, it could be something else that
got thrown upon creating the control's handle (ie in the Load event of
that form).
If you wish to refer to your forms in VB6 style (ie FormTypeName.show),
then I would recommend creating them as singletons. To do that, just go
into the form's Windows Designer Generated Code and change the
constructor (the New() method) to be private, then up at the top of the
class declaration, just after the Inherits System.Windows.Forms.Form
(well, this can actually go anywhere except inside a method, but this
is where I usually put it for clarity's sake) and type the following:
Public ReadOnly Instance as YourFormTypeNameHere = New
YourFormTypeNameHere
Now, when you want to refer to this single instance of your form, you
do YourFormTypeNameHere.Instance... and do whatever you wish, ie
YourFormTypeNameHere.Instance.Show()