Create new "me"

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi,

Instead of doing this....


Public Class Form1
Public Shared Sub CreateAndShow()
Dim f As New Form1
f.Show()
End Sub
End Class

I would like to make it generic by doing something like...

Public Class Form1
Public Shared Sub CreateAndShow()
Dim f As New Me
f.Show()
End Sub
End Class

.... but "Me" is not accepted, neither is "Dim f As New TypeOf(Me)".

I would like to put the CreateAndShow in a base form and then inherit from
it and still be able to use the CreateAndShow method.

Any suggestions? TANKS!!! :o)

M O J O
 
That's a good idea, so I tried solving it as an exercise. The good
news is that it works.

The bad news is that I've been learning .NET for about a week, so I'm
rather embarassed to show you how I did it. But here goes:

Dim s1 As String = Me.ToString
' s1 is in the format "WindowsApplication1.Form1, Text: Form1"
' Now remove the part that isn't the class name.
Dim i1 As Integer = InStr(s1, ",")
If i1 > 0 Then s1 = Mid(s1, 1, i1 - 1)
' Note: Can't use Left(s1, i1-1) above - for some reason VB thinks
I'm trying to
' access Me.Left instead! <grrr>
Dim objNewForm As Object =
Activator.CreateInstance(Type.GetType(s1))
Dim frm As Form = DirectCast(objNewForm, Form)
frm.Show()
 
Ok, I worked on it some more, and this version is far less embarrasing!
Enjoy:

DirectCast(Activator.CreateInstance(Type.GetType(Me.GetType.ToString)),
Form).Show()
 
If i1 > 0 Then s1 = Mid(s1, 1, i1 - 1)
' Note: Can't use Left(s1, i1-1) above - for some reason VB thinks
I'm trying to
' access Me.Left instead! <grrr>

You can use the line:

Imports VB = Microsoft.VisualBasic

before your code so that you can use VB.Left(s1, i1-1). That tells it that
you want to use VB as an abbreviation for Microsoft.VisualBasic.

Also, if you use Option Strict On, it will tell you when things don't match
up the way they should.

HTH

Andrew
 
Hi teslar91,

Thanks for helping me out here.

My problem is, that I can't use "Me", so your solution...

Public Shared Sub CreateAndShow()
Dim s1 As String = Me.ToString
' s1 is in the format "WindowsApplication1.Form1, Text: Form1"
' Now remove the part that isn't the class name.
Dim i1 As Integer = InStr(s1, ",")
If i1 > 0 Then s1 = Mid(s1, 1, i1 - 1)
' Note: Can't use Left(s1, i1-1) above - for some reason VB thinks'm
trying to
' access Me.Left instead! <grrr>
Dim objNewForm As Object = Activator.CreateInstance(Type.GetType(s1))
Dim frm As Form = DirectCast(objNewForm, Form)
frm.Show()
End Sub


.... gives me this error:

'Me' is valid only within an instance method.

I need to call the sub inside a shared sub, so I don't have an instance yet.

Any other suggestions? :o(

M O J O
 
'Me' is valid only within an instance method.

I need to call the sub inside a shared sub, so I don't have an instance
yet.

Any other suggestions? :o(

M O J O

Static (shared) methods don't have a "Me". They are applicable to any
instance, hence cannot work on any specific instance. In this case you have
to pass in a "Me" as a parameter.
 
Mojo,

It is possible to create objects from classes. But never objects from
objects. (Although object is a class itself as well. To be more precise the
highest class from which every thing derives).

The startup form is a kind of strange thing in VB.Net (but handy) it has
inbuild a Sub main, where in it creates an object from itself. For the same
case you use a Module or Shared Class in which you can create your form
object. Than you can create as much objects from that class as you wish.

I hope this gives an idea.

Cor
 
Hello M O J O,

What's the point of this? If the goal is to not have to call .Show when
you create a form (lazy-ass).. then add Me.Show to the base form's ctor.

-Boo
 
M said:
My problem is, that I can't use "Me", so your solution... [...]
... gives me this error:

'Me' is valid only within an instance method.

I need to call the sub inside a shared sub, so I don't have an
instance yet.

Try this:

\\\
Dim myTypeName As String
Dim myObject As Object

'Get the name of the type of this class
myTypeName =
Reflection.MethodBase.GetCurrentMethod.DeclaringType.ToString
'Create a new instance of this type
myObject = Activator.CreateInstance(Type.GetType(myTypeName))
///

This can be used in a Shared method. It uses Reflection to get a handle to
the executing method, and from there to the type that contains that method
(i.e., your class). It then uses the Activator object to create a new
instance of an object of that type. Hopefully this will get you closer to
where you want to be?
 
-Boo,
Must you berate everyone?


GhostInAK said:
Hello M O J O,

What's the point of this? If the goal is to not have to call .Show when
you create a form (lazy-ass).. then add Me.Show to the base form's ctor.
-Boo
 
Hello Steve,

I'll berate whoever I want. Must you be so freakin sensitive? Grow a pair,
ya pansy.

-Boo
 
Watching Boo's replies to this and another recent post about retaining
changed values of a textbox, I think I see the reason. Boo does not
post to this NG to actually help anyone with VB, he's only here to show
everyone how much he knows. So if someone posts a question where he
can't do that, it shows in the caustic reply.

Boo, if the SNR is too high for you here, ignore it. As this is a
public NG, you are going to get all kinds of clueless nubes posting
stupid questions. Find a better way to deal with it so you can play
nicely.
 
Oenone said:
Try this:
[...]

Which, ahem, can of course be optimised to this (apologies for the
wrapping):

\\\
Dim myObject As Object

'Create a new instance of this type
myObject =
Activator.CreateInstance(Reflection.MethodBase.GetCurrentMethod.DeclaringType)
///
 
Oerlone,

And do you think that this is a acceptable performing method for any
problem?

While you just can do

Dim myObject as new Myform (jor whatever other class)

Reflection is the same as setting the horse behind the cart.

Cor

"Oenone" <[email protected]
om> schreef in bericht news:[email protected]...
Oenone said:
Try this:
[...]

Which, ahem, can of course be optimised to this (apologies for the
wrapping):

\\\
Dim myObject As Object

'Create a new instance of this type
myObject =
Activator.CreateInstance(Reflection.MethodBase.GetCurrentMethod.DeclaringType)
///
 
Cor said:
And do you think that this is a acceptable performing method for any
problem?

I think it's what the OP asked for. Whether he's doing it the best way is up
to him, but he asked a question and I gave him an answer.

I can't see why that would have any noticeable performance penalty, anyway.
If he's doing this to manage the opening of forms, it'll be called .. what,
a couple of dozen times per app run?
 
Oenone,
I can't see why that would have any noticeable performance penalty,
anyway. If he's doing this to manage the opening of forms, it'll be called
.. what, a couple of dozen times per app run

You are right, but in my idea is Reflection something that should be used if
there is no other solution. I get more and more the idea that it is a kind
of toy. It is late binding you know.

Cor
 
Hi Oenone,

Thank you!!!!!!!

It is the only solution I've seen so far and it works. The performance
penalty is not noticeable.

:o)

THANKS!!!!!!!!!!!

M O J O
 
Hi Cor,

I was hoping that since my shared sub was inside a class, vb somehow new
what type of class the shared sub was called from.

I'm building a CRM system for my company. I want to have a base form that
can inherit all my form from. This base form will have many base stuff ....
forexample I will have three diferent ways to create and show a form ...

1) Normal - just create the form and show it.

2) Single instance - if the form is not yet created, create the form an show
it.

3) Single instance by ID - if for example the customer-form with customer
ID=xxx is not showing, create the form and show it, else show it.

Hope you get my pont.

Here's my code so far (beware of wrappings)....


Public Class BaseForm

Private _singleInstanceID As Guid
Private Shared _singleInstances As Dictionary(Of Guid, BaseForm)


Public Shared Sub CreateAndShowNormal(Optional ByVal owner As
IWin32Window = Nothing)
Dim f As Object =
Activator.CreateInstance(Reflection.MethodBase.GetCurrentMethod.DeclaringType)
DirectCast(f, BaseForm).Show(owner)
End Sub


Public Shared Sub CreateAndShowSingleInstace(Optional ByVal owner As
IWin32Window = Nothing)
Call CreateAndShowSingleInstace(Guid.Empty, owner)
End Sub


Public Shared Sub CreateAndShowSingleInstace(ByVal ID As Guid, Optional
ByVal owner As IWin32Window = Nothing)
If _singleInstances Is Nothing Then
_singleInstances = New Dictionary(Of Guid, BaseForm)
End If

Dim f As BaseForm

If Not _singleInstances.ContainsKey(ID) Then
Dim fa As Object =
Activator.CreateInstance(Reflection.MethodBase.GetCurrentMethod.DeclaringType)
f = DirectCast(fa, BaseForm)
f._singleInstanceID = ID
_singleInstances.Add(ID, f)
AddHandler f.FormClosed, AddressOf SingleInstanceClosed
Else
f = _singleInstances(ID)
End If

f.Show()
f.Focus()
End Sub


Private Shared Sub SingleInstanceClosed(ByVal sender As Object, ByVal e
As FormClosedEventArgs)
_singleInstances.Remove(DirectCast(sender,
BaseForm)._singleInstanceID)
End Sub

End Class


If there's a better way to do it, please let me know.

Thanks!

:o)

M O J O
 
Mojo,

You could use a variation on the GoF's Prototype pattern. Basically,
it provides the ability for objects to create other instances of
themselves. Actually, it's very similar to cloning.

Brian
 
Back
Top