|
-
Mar 13th, 2006, 12:37 AM
#1
Thread Starter
Lively Member
OO Question - Superclass / Subclass
Hi Everybody!
Im brand new to .Net and I've got to say Im lovin it so far!
Got a question though...
I have an MDI Child and I want to refer to it like so....
Private Sub DisplayForm(ByRef frm as System.Windows.Forms.Form)
{
}
I may be passing multiple different MDI children to this subroutine. When I turn on Option Strict it says it cannot perform an implicit conversion.
Please correct me but I was under the impression that OO polymorphism (Superclass <-> Subclass) would take care of this?
How would I delcare the subroutine so it could accept my child forms.
Thanks for your input.
-
Mar 13th, 2006, 12:43 AM
#2
Re: OO Question - Superclass / Subclass
Each one of your forms inherits System.Windows.Forms.Form
When you create your Form, it's based on .Net's Form but then you modify it making it different.
So it you have 3 forms called FormAbout, FormMain, and FormYippy, they are not System.Windows.Forms.Forms anymore. It would be like trying to pass a Double to a function that is waiting for an Int.
Depending on what you want to do, you may be able to cast it but if they're very different it may be a better idea to re-do your logic.
-
Mar 13th, 2006, 12:57 AM
#3
Thread Starter
Lively Member
Re: OO Question - Superclass / Subclass
WOW That was quick!
Hmmm your probably right, a logic redesign may be the way to go. This is what I'm trying to do...
VB Code:
Private WithEvents frmCRpt As frmCampRpt
Private WithEvents frmCMan As frmCampMan
Private Sub tbMain_ButtonClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolBarButtonClickEventArgs) Handles tbMain.ButtonClick
Select Case tbMain.Buttons.IndexOf(e.Button)
Case 0
DisplayForm(frmCRpt, 0)
Case 1
DisplayForm(frmCMan, 1)
Case 2
'DisplayForm(x, 2)
End Select
End Sub
Private Sub DisplayForm(ByRef frm As Windows.Forms.Form, ByVal iBtnIndex As Integer)
Try
If frm Is Nothing Then
Select Case iBtnIndex 'Select Form Type
Case 0
frm = New frmCampRpt
Case 1
frm = New frmCampMan
End Select
frm.MdiParent = Me
frm.Show() 'Show new instance
tbMain.Buttons(iBtnIndex).Pushed = True
Else
If frm.WindowState = FormWindowState.Minimized Then
frm.WindowState = FormWindowState.Normal
End If
frm.BringToFront() 'Show existing instance
End If
Catch
End Try
End Sub
Private Sub frmCRpt_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles frmCRpt.Closed
tbMain.Buttons(0).Pushed = False
frmCRpt = Nothing
End Sub
So I’m trying to determine if the MDI Child form has been displayed and if so just bring it to the front without creating another instance. This is so a user can enter some info into a form, go to another form, then return to the original form in the state they left it. As you can see this is hanging off a toolbar control which I am mimicking the behavior of a task bar, hence the 'tbMain.Buttons(iBtnIndex).Pushed = True' line of code.
I assumed that I would be able to refer to the Superclass like I was able to back in the days of C++ 6.0.
The code above works, but if wanting to be type safe, it breaks... 
I suppose the obvious logic redesign is to pack all this logic into the Toolbar's Click event. This would eliminate the need to pass the form. Conversely there would be alot of repeated code in each Case statement...
Any thoughts, ideas or suggestions?
Last edited by GottaGetITDone; Mar 13th, 2006 at 01:14 AM.
-
Mar 13th, 2006, 01:24 AM
#4
Re: OO Question - Superclass / Subclass
What you're doing is all correct except for one problem. You are passing the first parameter by reference. It's not the fact that you are passing an instance of a derived class into the method that's the problem. It's the fact that you're passing an instance of the base class back out again. Change the ByRef to ByVal and watch the error disappear. The reference you pass out is type Form and you're assigning it to variable of a derived class, and that's the implicit conversion that's not allowed. You could convert the procedure to a function, pass the parameter by value and then return a reference to the new form, which you could cast as the correct type:
VB Code:
Private WithEvents frmCRpt As frmCampRpt
Private WithEvents frmCMan As frmCampMan
Private Sub tbMain_ButtonClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolBarButtonClickEventArgs) Handles tbMain.ButtonClick
Select Case tbMain.Buttons.IndexOf(e.Button)
Case 0
frmCRpt = DirectCast(DisplayForm(frmCRpt, 0), frmCampRpt)
Case 1
frmCMan = DirectCast(DisplayForm(frmCMan, 1), frmCampMan)
Case 2
'DisplayForm(x, 2)
End Select
End Sub
Private Function DisplayForm(ByVal frm As Windows.Forms.Form, ByVal iBtnIndex As Integer) As Form
Try
If frm Is Nothing Then
Select Case iBtnIndex 'Select Form Type
Case 0
frm = New frmCampRpt
Case 1
frm = New frmCampMan
End Select
frm.MdiParent = Me
frm.Show() 'Show new instance
tbMain.Buttons(iBtnIndex).Pushed = True
Else
If frm.WindowState = FormWindowState.Minimized Then
frm.WindowState = FormWindowState.Normal
End If
frm.BringToFront() 'Show existing instance
End If
Catch
End Try
Return frm
End Function
That's quite inelegant though. I'd suggest making your child forms singletons and then you simply refer to their Instance properties at all times. The forms themselves will take care of creating an instance if one is required.
-
Mar 13th, 2006, 01:28 AM
#5
Re: OO Question - Superclass / Subclass
Here's what a basic singleton class looks like:
VB Code:
Public Class Singleton
'The one and only instance.
Private _instance As Singleton
'Make the constructor private so that an instance cannot be created from the outside.
Private Sub New()
End Sub
Public ReadOnly Property Instance() As Singleton
Get
If Me._instance Is Nothing Then
'No instance exists so create one.
Me._instance = New Singleton
End If
'Return a reference to the one and only instance.
Return Me._instance
End Get
End Property
End Class
-
Mar 13th, 2006, 01:59 AM
#6
Thread Starter
Lively Member
Re: OO Question - Superclass / Subclass
"I see!" said the Blind Man.
You are correct changing the parameter pass type to 'ByVal' removes the compile error.
Singleton - This is the sort of answer I was looking for. I know nothing of this Singleton but your explanation shows its the way to go. I will spend some time researching this solution and post when properly developed.
I currently have 3 VB.Net & 1 Crystal Reports.Net text books on order...man I cant wait.
Thank You jmcilhinney - Much appreciated
Last edited by GottaGetITDone; Mar 13th, 2006 at 02:04 AM.
-
Mar 13th, 2006, 02:47 AM
#7
Re: OO Question - Superclass / Subclass
That code was not quite correct. The '_instance' variable and 'Instance' property should be Shared. Here's code for a VB 2005 singleton form class:
VB Code:
Public Class SingletonForm
Private Shared _instance As SingletonForm
Public Shared ReadOnly Property Instance() As SingletonForm
Get
If _instance Is Nothing OrElse _instance.IsDisposed Then
_instance = New SingletonForm
End If
Return _instance
End Get
End Property
Private Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
End Class
and here's how you would use it:
VB Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Make the form visible in case it is not already.
SingletonForm.Instance.Show()
'Focus the form in case it was already visible.
SingletonForm.Instance.Activate()
End Sub
There's no need for class level variables for the forms because you simply refer to the Shared Instance property all the time. Note that the IsDisposed part in the Instance property takes care of creating a new instance if the old instance was closed.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|