Can I do this if the type only has constructors as:
Sub New()
End Sub
Or can I call a constructor that takes params if necessary, I might night need this though.
Main Topics
Browse All TopicsI have the following three methods in my main MDI Parent form to handle form transitions:
Public Sub SwitchToFormAndCloseMe(ByV
If sender IsNot Nothing Then
sender.Close()
End If
HandleShowChild(toForm)
End Sub
Private Sub HandleShowChild(ByRef toForm As Form)
If IsChildInMemory(toForm.Get
toForm.Show()
Else
'Need to create a new form of this type and show it
End If
End Sub
Private Function IsChildInMemory(ByVal childType As Type) As Boolean
Dim frmChild As Form
For Each frmChild In Me.MdiChildren
If frmChild.GetType() is childType Then
Me.ActivateMdiChild(frmChi
Return True
End If
Next
Return False
End Function
Basically I need to implement the commented bit "Need to create a new form of this type and show it"
My usage of this is like:
Main.SwitchToFormAndCloseM
I am open to better suggestion or best practices for form transitions, I don't want the main form to have to hold an instance of the the child forms. So want to dynamically create a form intance of the provided type and show it. Also should my methods be ByRef or ByVal for this? Can I acheive this with Generics? I have never used Generics except to hold a stronly typed List.
Thanks
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
This is my method as follows:
Private Sub HandleShowChild(ByVal type As Type)
ResetStatus()
If IsChildInMemory(type) Then
the found form is activated in IsChildInMemory
Else 'Create a new instance and show it
Dim newForm = CType(System.Activator.Cre
newForm.Show()
End If
End Sub
I would like to constraing the Type permissable to this function to only objects which inherit from Form. Also I don't like:
Dim newForm = CType(System.Activator.Cre
newForm.Show()
As newForm is not typed haven't tested if this will work yet as object. Ideally want something like:
Dim newForm as typeof(type) = CType(System.Activator.Cre
newForm.Show()
> Or can I call a constructor that takes params if necessary
Yes, you can:
CreateInstance ( type As Type, ParamArray args As Object() )
> I would like to constraing the Type permissable to this function to only objects which inherit from Form.
You can use:
if type.BaseType == typeof(System.Windows.Form
Sorry for C# sysntax
>Ideally want something like
I don't it is possible w/o some switch and one-by-one checking.
OK I have got this far:
Public Sub SwitchToFormAndDisposeMe(B
If sender IsNot Nothing Then
sender.Dispose()
End If
HandleShowChild(toFormType
End Sub
Private Function IsChildInMemory(ByVal childType As Type) As Boolean
Dim frmChild As Form
For Each frmChild In Me.MdiChildren
If frmChild.GetType() Is childType Then
Me.ActivateMdiChild(frmChi
Return True
End If
Next
Return False
End Function
Private Sub HandleShowChild(ByVal type As Type)
ResetStatus()
If IsChildInMemory(type) Then
'Ignore the provided form, just activate the found form
Else 'Create a new instance of this type and show it
Dim newForm = System.Activator.CreateIns
PrepareAndShowForm(newForm
End If
End Sub
I can show the new Form yah! However I am sure how best to call
SwitchToFormAndDisposeMe(.
On another form I am calling as follows:
SwitchToFormAndDisposeMe(M
but this actually calls the Sub New of form frmXX I want a solution that does not instantiate the object I just need to pass an objects type information for compare to the Switch function, the main controlling MDI will handle instantiation of new Forms. I am so close I can feel it!
Thanks
Ok I am a litte confused now myself.
I am on FormA, I want to switch to FormB. I don't want to instantiate an instance of FormB inside class A, I want this all to handled in my Main class. I know the type I want to switch to, but I don't want to make an instance here.
Public Class FormA
Private Sub Button1_Click( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Main.SwitchToFormAndCloseM
End Sub
End Class
How am I best to get the type of a class that I want, pass it to switch, let it handle it appropriately?
Thanks
I am coding in C# too :)
I can recommend the following:
If you call FormA.ShowDialog() from Main class, so Main class knows when FormA is closed and can handle it.
If you call FormA.Show() from Main class, you can add OnClose event handler to FormA in your Main class and handle this event as well.
If from some reason you don't want to create an instance of FormB in FormA (although FormA decides which Form should be opened after itself), you can add some property FormToOpenAfterMe to FormA. Main class will use this property an open whatever you want.
I hope I understood you :)
if you know the object you are passing is a form - forma and formb are inherrited from system form.
in SwitchToFormAndCloseMe(Me,
http://msdn2.microsoft.com
public sub SwitchToFormAndCloseMe(a as form, b as form)
'//simple - dont care because its a form
a.close
b.show
if b.gettype= gettype(FormB) then
with directcast(FormB)
'//do what you need
end with
endif
end sub
youll have to excuse me if that was a bit jumbled - just woke up
I want to able write code in FormA button click like
Main.SwitchToFormAndDispos
and let main dispose A and create a new instance of FormB and show it,
I am not sure of the VB.net syntax for this, at the moment I am getting an erro telling me to "Insert the missing Is"
Also not sure what param my Main.SwitchToFormAndDispos
So close but just not quite getting it.
Thanks heaps, you have been excellent help.
If anyone can confirm this that would be awesome, it's just that this is an existing applicaiton I have to work on with quite a few forms, it would take some time to refactor the solution and shift all processing to Load. Plus I think it's a cleaner solution if I don't have to create an instance, I shouldn't need to.
Thanks
This is code now (I just don't know how to call it):
Private Sub HandleShowChild(ByVal providedType As Type)
ResetStatus()
If IsChildInMemory(providedTy
'Ignore the provided form, just activate the found form, done in IsChildInMemory
Else 'Create a new instance of this type and show it
If providedType.BaseType() is GetType(Windows.Forms.Form
Dim newForm = System.Activator.CreateIns
PrepareAndShowForm(newForm
Else
Throw New ArgumentException("Type must inherit form System.Windows.Form, provided type inherits from: " & providedType.BaseType.ToSt
End If
End If
End Sub
Also:
If providedType.BaseType() is GetType(Windows.Forms.Form
fails for forms where I am using Visual Inheritance on Forms, so the baseType of the passed form is actually MyBaseForm, so I need to check
If providedType.BaseType() is GetType(Windows.Forms.Form
Obviously this would only ever work for 2 levels of Inherited forms, what is a good solution for this, if you recursively kept call baseType you would get all the way to System.Object, how do you know when to stop or is there some other attribute on Type I should be testing against?
Thanks
>>
im not 100% sure on this but i think anytime you refer to a class in vb the new sub fires.
<<
In VB (up to 6) and in VB.NET 2005, there is a "default instance" of any Class based on Form: this was not the case in VB.NET 2002 or 2003.
What this means (I haven't followed the full thread by the way, so it may not be appropriate to your current needs) is that you can, anywhere in the Namespace within which a Form's class file exists, simply refer to that TYPE and it will (if one does not already exist) create an instance. If you only want one instance of that TYPE then you have no need expressly to instantiate it. If you want more that one instance, you will need to go down the "normal" route - like
Dim myForm1 As New FormType
- for other instances, and keep track of those instances. But for the "default instance" just referring to the TYPE is enough.
Roger
The thing is I don't want an instance, I do not want the Form's Sub New to be called. I want to call code like the following with the type of the class, and let this method create an intance of that class. I do not want the Constructor of that class to called before I pass the params to this method.
Private Sub HandleShowChild(ByVal providedType As Type)
ResetStatus()
If IsChildInMemory(providedTy
'Ignore the provided form, just activate the found form, done in IsChildInMemory
Else 'Create a new instance of this type and show it
If providedType.BaseType() is GetType(Windows.Forms.Form
Dim newForm = System.Activator.CreateIns
PrepareAndShowForm(newForm
Else
Throw New ArgumentException("Type must inherit form System.Windows.Form, provided type inherits from: " & providedType.BaseType.ToSt
End If
End If
End Sub
Have a look at the last post in this thread.
http://www.experts-exchang
I still haven't mastered everything in this thread but, from what I have read, my feeling is that the approach outlined there might meet your needs
Roger
Just read it, doesn't quite fit my requirements. Calling:
ShowForm(thatForm)
Will create an instance of thatForm, I do not want this. I want to pass the Type of thatForm to the Main module and let it create the Type if it does not already exist in my MDIChild collection else show the form. I do not want it to create an instance in the callingForm as the Constructor to thatForm does quite a bit of work, there is alot of code to refactor if I had to shift processing from New() -> Load
Kind Regards
gena17
IsInstanceOfType I am having some trouble with.
If (GetType(System.Windows.Fo
Dim newForm = System.Activator.CreateIns
PrepareAndShowForm(newForm
Else
Throw New ArgumentException("Type must inherit form System.Windows.Form, provided type inherits from: " & providedType.BaseType.ToSt
End If
I am getting the argException thrown as providedType.Base Type is System.Windows.Form not System.Windows.Forms.Form
If I try and check for:
(GetType(System.Windows.Fo
VS 2005 tells me "System.Windows.Form" is not defined. I have check my base forms they all inherit from System.Windows.Forms.Form
this is a strange one!
>>
Calling:
ShowForm(thatForm)
Will create an instance of thatForm, I do not want this.
<<
I beg to differ. If you are calling your sub HandleShowChild it means you DO want an instance of your form type.
The question that sub is answering is whether it already exists or not. If it does exist (in its default instance) then the call with reference to its Type will not create a new instance. If it does not exist then you will need to create it in order to show it. I am not clear why creating it in calling the sub rather than in the sub itself makes any operational difference.
I think the point is that - although the call to the HandleShowChild sub may be made within "the calling form", it does not (EMPHASIS added) "create an instance IN the callingForm". Because you are calling the default instance by TYPE it is (on my understanding) created "at large". If you then add that default instance to (e.g.) an MDI parent's children or expressly make its parent or its owner the calling form then it will exhibit the behaviour appropriate to those relationships. But that does not mean that, as the default instance, just because it was first referred to in one particular form it is created IN that form.
Let me stress that I am not saying that the alternative approach being discussed in this thread is wrong. It's just that, unless I have misunderstood the requirements, it seems more complicated than the existance of default instances requires.
Roger
Ok so I need to just be sure on this. Also I am not quite sure what you mean by "default instance" If I have a form called FormA and FormB, and their will be many switchings between these MDIChild forms I only every want to call the constructor of each form once for the life of the application. If I change to use your ShowForm method to take a form and if my usage is as follows:
Public Class FormA
Inherits System.Windows.Forms.Form
Private Sub btnShowFormB_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShowFormB.Click
Main.ShowForm(Me, FormB) 'not explicitly creating an instance
End Sub
End Class
Public Class FormB
Inherits System.Windows.Forms.Form
Private Sub btnShowFormA_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShowFormA.Click
Main.ShowForm(Me, FormA) 'not explicitly creating an instance
End Sub
End Class
Then are you saying that a defualt instance of each form gets constructed only once, or this will happend everytime the the button is clicked, I don't want Sub New to called over and over. Form Load can be called multiple times, this is not a problem
Thanks
Yes, that's what I'm saying. It will, of course, depend on what you do with FormA while you're not using it. If you .Close it, then the "default instance" will no longer exist, so when you call ShowForm(FormA) again, its .New will be fired again. So, to avoid re-firing, an unused form will need to be hidden rather than disposed of. And, as I say, it will only work if you only want ONE instance of FormA, ONE instance of FormB, etc. And it won't work with VB.NET 2002 or 2003.
To test it, stick (temporary) debugging code in your child forms' .New subs on these lines
Debug.WriteLine("FormA.New
As to a more elegant, Generics approach, I'm not sure. As this one works for me, I haven't tried it ;-)
Roger
You are right Roger I just tested it. Cool it works as you described I will implement in this fashion from here in. The constructors only get called once. Wierd concept of MS but helpful.
Also some of the MDIChildren call ShowDialog for some small forms to get users data in a textbox etc, very simple forms. Yet this dialog which comes up is not linked at all to the MDIChild or Parent so if I click minimise on the parent this Dialog (MDIChild) still remains center screeen and active. Of you hit "Show Desktop" on the Windows QuickLaunch the MDIParent is minimised but the dialog still floats above all other applications, even on alt-tabing to other running applications.
Any idea how do I fix this?
What is my best practice for showing Modal Dialogs off an MDIChild?
Thanks
Glad the ShowForm thing works OK.
>>
What is my best practice for showing Modal Dialogs off an MDIChild?
<<
I recognise the description re that from your current question in VB.NET (which is really my "home" TA). I didn't chip in there because I don't think there's an easy answer. I think you'll have to "self-code" the modality. This is because the two built-in elements - MDI parent/children on the one hand and modal forms (i.e. used with showdialog) on the other - seem to me to be incompatible. The MDI concept has everything working WITHIN the MDI frame (in program terms, not just visually). Modal forms function OUTSIDE that frame. The whole point of ShowDialog is that the user cannot do anything else until s/he has properly responded to the form concerned.
The EFFECT of modality is obviously achievable - e.g. consider the MS Word Find/Replace "dialog" in its MDI environment - but I haven't found a straightforward way of doing it just with the "normal" VB.NET mechanisms.
Here's a PAQ which might help
http://www.experts-exchang
It's the Accepted Answer post near the end that might be relevant: there was a lot of "round the houses" stuff before we got to an answer in that case.
Roger
I am not sure where to start with this. I have normal form transitions going really well now.
I am at the stage at several leafs within the from menu/wizard hierarchy where the existing code has about 10 buttons on a form, each one opens a model ShowDialog() allows the user to edit some grids etc click Ok, Cancel. The container form then checks the DialogResult of that model form, it OK update(dataset) If cancel RejectChanges is being called.
So now I am presented with scenario I would have to change all the forms to call show, put the dataset update code inside the OK click handle, move the RejectChanges into the OnClose of the form, test for DialogResult Cancel if true Reject Changes?
Any other suggestion or do I just have to refactor all these forms to conform to this scenario, I can achieve modal likeness, by calling Show on the current Dialogs and also setting the FormStyleBorder as None and Dock to Fill. So you only can ever work on one form at a time. This is the way the application intends the user to drive it anyway.
Regards
I think you can keep your data-processing on the calling form. Get the calling form to listen for a (self-coded) event that is raised by the called form (the "dialog") with a Save or Cancel argument depending which button is pressed. And the same approach - waiting for the firing of an event from the "dialog" - could at the same time implement the "wait for a result then carry on" requirement that you mention. In the latter context, I would envisage the calling form's calling code ending with the showing of the "dialog", and then separate code to save or reject the changes when the called form fires its event.
This is brainstorming - which means I've done no testing ;-). And it's not ideal, even in brainstorming terms. But whatever you do is going to have to be a compromise, and this approach might hit a better balance between saving as much as you can of what you've got at the moment and having extensively to refactor for the new environment.
I've written in general terms, because details would depend on minutiae of your set-up which I don't know. If the general idea appeals but you need to discuss details, it might be helpful if you posted sample code for the "dialog calling" and "data processing" operations of a calling form and the subs from a "dialog" form.
Roger
Sounds good, how would I force the calling form to "wait" for this event?
Also the client is very picky about the look and feel of the application (they are a media house). I need to paint the MDI Parent container with a gradient effect. I have tried handling the Paint event of the MDI Parent and doing it here, but it is not working. Ideally I would paint this effect in the child container, set all MDI Child form's background to transparent and the app would look good, all the labels would have to support transparency as well.
What is my best and most efficient (the current forms a quite flickery (I think due to the bind of the syncfusion grids)), to implement this requirement? or should I open another question?
Regards
Ok I have sorted the MDI Parent paint using the solution found at the bottom here:
http://www.bobpowell.net/m
However I am trying to do this for child forms:
Private Sub PrepareAndShowForm(ByRef childForm As Form)
PrepareForm(childForm)
childForm.BackColor = color.Transparent
childForm.Visible = True
childForm.Show()
End Sub
As I set my MDI child windows to have FormStyleBorder as None and Dock to Fill, they function really like a panel, I'd like each MDI child to support transparency and pick up the gradient background form the MDI Parent, also to support transparent lables on the child. Is this acheivable? or do I need to change all my existing form to inherit from panel instead of Form, what would be the consequences of this?
Thanks
>>
how would I force the calling form to "wait" for this event?
<<
Put a sub to handle it in the calling form. And then either declare the called form WithEvents (but that means you would have to declare it at form level) or add a handler when you do declare it
AddHandler CalledForm.Event, AddressOf CallingFormEventHandler
On the painting side, it sounds as though you're now happy with what you've got but, if not, another question would be better. Display issues are not my forte.
If, for display purposes, you decide to replace your forms by panels you wouldn't be able to use the MDI parent's child forms collection to organise / control them. And you'd have to self-code Events (e.g. like FormClosing) that exist in Forms but not in Panels. But, as I remarked before, you're in a "having to compromise" situation, and you're really the only one that can decide where the best compromise is.
Roger
I still not qutie getting you. In calling form
dialogForm.Show(Me)
'Need to Wait here till I get an event from dialogForm only once I have that result step down to the Process() method
'Do some other processing
Process()
This behaviour works if I dialogForm.ShowDialog(Me),
Thanks
>>
In the latter context, I would envisage the calling form's calling code ending with the showing of the "dialog", and then separate code to save or reject the changes when the called form fires its event.
<<
So ...
'[....]
AddHandler dialogForm.Event, AddressOf CallingFormEventHandler
dialogForm.Show(Me)
End Sub
Private Sub CallingFormEventHandler
'Do some other processing
Process()
End Sub
Roger
Business Accounts
Answer for Membership
by: gena17Posted on 2006-12-17 at 00:51:30ID: 18154144
craigdev,
tance(type ) method.
You can use
System.Activator.CreateIns
It creates an instance of the specified type and returns it to you.