Results 1 to 7 of 7

Thread: OO Question - Superclass / Subclass

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Mar 2006
    Posts
    65

    Smile 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.

  2. #2
    KrisSiegel.com Kasracer's Avatar
    Join Date
    Jul 2003
    Location
    USA, Maryland
    Posts
    4,985

    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.
    KrisSiegel.com - My Personal Website with my blog and portfolio
    Don't Forget to Rate Posts!

    Free Icons: FamFamFam, VBCorner, VBAccelerator
    Useful Links: System.Security.SecureString Managed DPAPI Overview Part 1 Managed DPAPI Overview Part 2 MSDN, MSDN2, Comparing the Timer Classes

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Mar 2006
    Posts
    65

    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:
    1. Private WithEvents frmCRpt As frmCampRpt
    2.     Private WithEvents frmCMan As frmCampMan
    3.  
    4.     Private Sub tbMain_ButtonClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolBarButtonClickEventArgs) Handles tbMain.ButtonClick
    5.  
    6.         Select Case tbMain.Buttons.IndexOf(e.Button)
    7.             Case 0
    8.                 DisplayForm(frmCRpt, 0)
    9.             Case 1
    10.                 DisplayForm(frmCMan, 1)
    11.             Case 2
    12.                 'DisplayForm(x, 2)
    13.         End Select
    14.     End Sub
    15.  
    16.     Private Sub DisplayForm(ByRef frm As Windows.Forms.Form, ByVal iBtnIndex As Integer)
    17.  
    18.         Try
    19.             If frm Is Nothing Then
    20.                 Select Case iBtnIndex               'Select Form Type
    21.                     Case 0
    22.                         frm = New frmCampRpt
    23.                     Case 1
    24.                         frm = New frmCampMan
    25.                 End Select
    26.                
    27.                 frm.MdiParent = Me
    28.                 frm.Show()                          'Show new instance
    29.  
    30.                 tbMain.Buttons(iBtnIndex).Pushed = True
    31.             Else
    32.                 If frm.WindowState = FormWindowState.Minimized Then
    33.                     frm.WindowState = FormWindowState.Normal
    34.                 End If
    35.                 frm.BringToFront()                  'Show existing instance
    36.             End If
    37.         Catch
    38.         End Try
    39.  
    40.     End Sub
    41.  
    42.     Private Sub frmCRpt_Closed(ByVal sender As Object, ByVal e As    System.EventArgs) Handles frmCRpt.Closed
    43.         tbMain.Buttons(0).Pushed = False
    44.         frmCRpt = Nothing
    45.     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.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    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:
    1. Private WithEvents frmCRpt As frmCampRpt
    2.     Private WithEvents frmCMan As frmCampMan
    3.  
    4.     Private Sub tbMain_ButtonClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolBarButtonClickEventArgs) Handles tbMain.ButtonClick
    5.  
    6.         Select Case tbMain.Buttons.IndexOf(e.Button)
    7.             Case 0
    8.                 frmCRpt = DirectCast(DisplayForm(frmCRpt, 0), frmCampRpt)
    9.             Case 1
    10.                 frmCMan = DirectCast(DisplayForm(frmCMan, 1), frmCampMan)
    11.             Case 2
    12.                 'DisplayForm(x, 2)
    13.         End Select
    14.     End Sub
    15.  
    16.     Private Function DisplayForm(ByVal frm As Windows.Forms.Form, ByVal iBtnIndex As Integer) As Form
    17.  
    18.         Try
    19.             If frm Is Nothing Then
    20.                 Select Case iBtnIndex               'Select Form Type
    21.                     Case 0
    22.                         frm = New frmCampRpt
    23.                     Case 1
    24.                         frm = New frmCampMan
    25.                 End Select
    26.  
    27.                 frm.MdiParent = Me
    28.                 frm.Show()                          'Show new instance
    29.  
    30.                 tbMain.Buttons(iBtnIndex).Pushed = True
    31.             Else
    32.                 If frm.WindowState = FormWindowState.Minimized Then
    33.                     frm.WindowState = FormWindowState.Normal
    34.                 End If
    35.                 frm.BringToFront()                  'Show existing instance
    36.             End If
    37.         Catch
    38.         End Try
    39.  
    40.         Return frm
    41.     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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    Re: OO Question - Superclass / Subclass

    Here's what a basic singleton class looks like:
    VB Code:
    1. Public Class Singleton
    2.  
    3.     'The one and only instance.
    4.     Private _instance As Singleton
    5.  
    6.     'Make the constructor private so that an instance cannot be created from the outside.
    7.     Private Sub New()
    8.  
    9.     End Sub
    10.  
    11.     Public ReadOnly Property Instance() As Singleton
    12.         Get
    13.             If Me._instance Is Nothing Then
    14.                 'No instance exists so create one.
    15.                 Me._instance = New Singleton
    16.             End If
    17.  
    18.             'Return a reference to the one and only instance.
    19.             Return Me._instance
    20.         End Get
    21.     End Property
    22.  
    23. End Class
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Mar 2006
    Posts
    65

    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.

  7. #7
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,222

    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:
    1. Public Class SingletonForm
    2.  
    3.     Private Shared _instance As SingletonForm
    4.  
    5.     Public Shared ReadOnly Property Instance() As SingletonForm
    6.         Get
    7.             If _instance Is Nothing OrElse _instance.IsDisposed Then
    8.                 _instance = New SingletonForm
    9.             End If
    10.  
    11.             Return _instance
    12.         End Get
    13.     End Property
    14.  
    15.     Private Sub New()
    16.         ' This call is required by the Windows Form Designer.
    17.         InitializeComponent()
    18.  
    19.         ' Add any initialization after the InitializeComponent() call.
    20.  
    21.     End Sub
    22.  
    23. End Class
    and here's how you would use it:
    VB Code:
    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2.         'Make the form visible in case it is not already.
    3.         SingletonForm.Instance.Show()
    4.  
    5.         'Focus the form in case it was already visible.
    6.         SingletonForm.Instance.Activate()
    7.     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.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width