8 Replies - 6865 Views - Last Post: 07 March 2011 - 03:48 PM Rate Topic: -----

#1 lukas_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 06-March 11

Passing User object between forms

Posted 06 March 2011 - 04:31 PM

I am having some difficulty getting my head around passing objects between forms and hoped someone might put me on the right track...

I have five forms: frmMain, frmLogin, frmAdminMode, frmUserMode, frmUserMode, frmUserModeDeep


There are two main use-cases: admin mode and user mode.

Admin Mode: As the project starts it runs frmMain. Clicking a button stops the autologin (simple timer) and will invoke frmLogin (using .ShowDialog). The user is prompted for the users' ID number (four digits) and pass-code (again four digits). frmLogin will query a back-end database to authorise or reject the login attempt (this bit is all working fine) and then return control to frmMain. If the user is a valid admin frmMain will then invoke frmAdminMode.

frmMain -> frmLogin
<- frmLogin
-> frmAdminMode


User Mode: The project starts and runs frmMain. Once the timer expires it automatically hides frmMain and invokes frmUserMode. There is a button on frmUserMode that invokes frmLogin allowing users to log in with their credentials. Successful login takes then to frmUserModeDeep.

frmMain -> frmUserMode -> frmLogin
<- frmLogin
-> frmUserModeDeep



At present I am creating properties in the Login form and querying that form from frmMain
Private Sub buttonAdminLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonAdminLogin.Click
Dim adminLogin As New frmLogin()
adminLogin.ShowDialog()
...
If Not adminLogin.ID = "" Then



EDIT: Somehow I submitted this before I was finished! I'm still working on it... :)

This post has been edited by lukas_: 06 March 2011 - 04:34 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Passing User object between forms

#2 lukas_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 06-March 11

Re: Passing User object between forms

Posted 06 March 2011 - 04:44 PM

I am having some difficulty getting my head around passing objects between forms and hoped someone might put me on the right track...

I have five forms: frmMain, frmLogin, frmAdminMode, frmUserMode, frmUserMode, frmUserModeDeep


There are two main use-cases: admin mode and user mode.

Admin Mode: As the project starts it runs frmMain. Clicking a button stops the autologin (simple timer) and will invoke frmLogin (using .ShowDialog). The user is prompted for the users' ID number (four digits) and pass-code (again four digits). frmLogin will query a back-end database to authorise or reject the login attempt (this bit is all working fine) and then return control to frmMain. If the user is a valid admin frmMain will then invoke frmAdminMode.

frmMain -> frmLogin
<- frmLogin
-> frmAdminMode


User Mode: The project starts and runs frmMain. Once the timer expires it automatically hides frmMain and invokes frmUserMode. There is a button on frmUserMode that invokes frmLogin allowing users to log in with their credentials. Successful login takes then to frmUserModeDeep.

frmMain -> frmUserMode -> frmLogin
<- frmLogin
-> frmUserModeDeep



At present I am creating properties in the Login form and querying that form from frmMain
Private Sub buttonAdminLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonAdminLogin.Click
Dim adminLogin As New frmLogin()
adminLogin.ShowDialog()
...
If Not adminLogin.ID = "" Then



This seems incredibly ugly to me and I wondered what the other options are.


The way I'd envisaged it I would be creating a user object with properties for ID, name, email, etc... which I could then 'return' back from the Login form. Unfortunately I cannot quite get my head around how this would be done. Alternatively I though it might be possible for me to pass a pointer to the user object, from frmMain to frmLogin, so that frmLogin could manipulate the user object directly.

I have tried this tutorial but I confess I am struggling to see how it'd work with in my scenario... http://www.dreaminco...es-byval-byref/



D@mn: It seems that I can no longer edit my post. Does anyone know how I can edit/delete it so I can post afresh? Much appreciated... :)
Was This Post Helpful? 0
  • +
  • -

#3 _HAWK_  Icon User is online

  • Master(Of Foo)
  • member icon

Reputation: 1057
  • View blog
  • Posts: 4,092
  • Joined: 02-July 08

Re: Passing User object between forms

Posted 06 March 2011 - 04:49 PM

I like events for things type of things. The event is on the frmLogin and when the login passes it raises this event. You now have a routed sub on the frmMain that now gets executed - here is where you address the type of login.
'frmLogin
Public Event SetLoginType(ByVal something As <sometype>))

'When the login passes
RaiseEvent SetLoginType(<sometype>)


'frmMain
Dim adminLogin As New frmLogin()
Addhandler adminLogin.SetLoginType, Addressof SetLoginType
'''

Private Sub SetLoginType(ByVal something As <sometype>)'same signature
  'this sub fires when you raise the event on the login form
  'do stuff
End Sub

This post has been edited by hawkvalley1: 06 March 2011 - 04:50 PM

Was This Post Helpful? 0
  • +
  • -

#4 lukas_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 06-March 11

Re: Passing User object between forms

Posted 06 March 2011 - 04:57 PM

I have tried:
Public Class frmMain
    Public AdminUser As New User()
    ...
    Private Sub buttonAdminLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonAdminLogin.Click
    Dim adminLogin As New frmLogin(AdminUser)
    tempLogin.ShowDialog()
    ...
    End Sub
...
End Class



Public Class frmLogin
...
    Public Sub New(ByVal objUser As User)
        MyBase.New()
        InitializeComponent()
    End Sub
...

Private Sub buttonEnter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonEnter.Click
    ...
    objUser.ID = reader("ID")
    ...
End Sub
...
End Class



Unfortunately it produces the error 'Object reference not set to an instance of an object'. I think I have misunderstood what is going on... :)


EDIT: @hawkvalley1 - that looks promising! I shall give it a try...

This post has been edited by lukas_: 06 March 2011 - 05:00 PM

Was This Post Helpful? 0
  • +
  • -

#5 demausdauth  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 178
  • View blog
  • Posts: 652
  • Joined: 03-February 10

Re: Passing User object between forms

Posted 07 March 2011 - 11:09 AM

Out of this section of code where do you define the class level variable that you are using and where do you set it?
Public Class frmLogin
...
    Public Sub New(ByVal objUser As User)
        MyBase.New()
        InitializeComponent()
    End Sub
...

Private Sub buttonEnter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonEnter.Click
    ...
    objUser.ID = reader("ID")
    ...
End Sub
...
End Class




Basically what I am asking is, in the button click event you are trying to set the ID property of the object objUser, but you don't have the object defined as a class level variable. Yes, you do have it defined in the New constructor as a parameter, but it you still need an object to work with in the context of frmLogin.
Was This Post Helpful? 0
  • +
  • -

#6 lukas_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 06-March 11

Re: Passing User object between forms

Posted 07 March 2011 - 01:51 PM

@demausdauth: I can see what you mean about the lack of defined object in the frmLogin class.

I had defined my User objects in the frmMain class as I perceived this to be the parent. I guess I was hoping for inherited scope... :)

Public Class frmMain
    Public AdminUser As New User()
    Public User1 As New User()
    Public User2 As New User()

    Private Sub buttonAdminLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonAdminLogin.Click
...




How can I declare/define a User object to work with the object objUser? Having read through http://www.dreaminco...es-byval-byref/ I imagine that Reference Type ByVal is the way to go but I am confused by the scope. In the example code given does foo only exist within the scope of the Sub SetText? If so how would I maintain the stack pointer beyond the scope of the constructor?

' Calling code:
Dim button1 As New Button
SetText(button1)
' ...
Sub SetText(ByVal foo As Button)
   foo.Text = "foobar"
End Sub





Once again I just want to say how much I appreciate the assistance.

PS: I figured out why I erroneously posted the original post earlier - I was tabbing in the code block and didn't notice it was jumping between the text box and the buttons! :)
Was This Post Helpful? 0
  • +
  • -

#7 lukas_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 06-March 11

Re: Passing User object between forms

Posted 07 March 2011 - 02:39 PM

Okay I think I have it...

In frmMain I declare and instantiate my User objects (do I have the terminology right?) so they are scoped for the frmMain class and pass the User object 'AdminUser' to the frmLogin constructor using Reference Type ByVal..

Public Class frmMain
    Public AdminUser As New User()
    Public User1 As New User()
    Public User2 As New User()

    Private Sub buttonAdminLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonAdminLogin.Click
        ' Hide frmMain...
        Me.Hide()
        ' ...and show the login form which will be used to authenticate the user
        Dim tempLogin As New frmLogin(AdminUser)
        tempLogin.ShowDialog()
    ...
End Class



Public Class login
    Public thisUser As User
    ...
    Public Sub New(ByVal objUser As User)
        MyBase.New()
        InitializeComponent()
        thisUser = objUser
    End Sub
    ...
End Class



Again if I have the terminology correct I am overloading(?) constructor?

Can I just check: in this scenario am I passing the value of the stack pointer rather than the value(s) of the object? And as I have not instantiated thisUser when it executes 'thisUser = objUser' it is simply setting the value of the stack pointer for 'thisUser' to the value of the stack pointer for 'objUser'? So when frmLogin sets a property of thisUser these changes can be seen in AdminUser as both stack pointers are pointing to the same memory space in the heap?



PS: Would it be better if I defined(?) the constructor as...

Public Sub New(Optional ByVal AdminUser As User = Nothing)
...



Or given that the form needs the stack pointer to the user object to actually do anything useful would it be best to leave it as is? I don't really want anyone to instantiate an instance of frmLogin without a User object to manipulate...
Was This Post Helpful? 0
  • +
  • -

#8 demausdauth  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 178
  • View blog
  • Posts: 652
  • Joined: 03-February 10

Re: Passing User object between forms

Posted 07 March 2011 - 02:40 PM

' Calling code:
Dim button1 As New Button
SetText(button1)
' ...
Sub SetText(ByVal foo As Button)
   foo.Text = "foobar"
End Sub




Quote

In the example code given does foo only exist within the scope of the Sub SetText?


Yes the object foo only exists within SetText.

Quote

If so how would I maintain the stack pointer beyond the scope of the constructor?


To maintain the connection to the object passed in the constructor you need a class level object that is set in the constructor. For instance:


'### frmMain
Public Class frmMain
    Public AdminUser As New User()
    ...
    Private Sub buttonAdminLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonAdminLogin.Click
    Dim adminLogin As New frmLogin(AdminUser)
    tempLogin.ShowDialog()
    ...
    End Sub
...
End Class

'### frmLogin
Public Class frmLogin
...
    'this is our class level User object variable, notice an instance is not created here it is only declared. We will get the instance from the constructor
    Private _loginFormUserObject As User
    
    'this is how we will access the private variable
    Public Property LoginFormUserObject() As User
        Get 
            Return _loginFormUserObject
        End Get
        Set (ByVal value As User)
            _loginFormUserObject = value
        End Set
    End Property

    Public Sub New(ByVal objUser As User)
        'set the class level variable to the passed user object
        LoginFormUserObject = objUser
        MyBase.New()
        InitializeComponent()
    End Sub
...

Private Sub buttonEnter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonEnter.Click
    ...
    'objUser.ID = reader("ID")
    LoginFormUserObject.ID = reader("ID")
    ...
End Sub
...
End Class





Here I created a class level variable on frmLogin called _loginFormUserObject. Notice it is declared as private and then we use a public property to access it and its properties. This way allows us to pass the object in the constructor and then modify the objects on the rest of the form. As long a new instance of the user is not created it will continue to point to the original object.
Was This Post Helpful? 1
  • +
  • -

#9 lukas_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 06-March 11

Re: Passing User object between forms

Posted 07 March 2011 - 03:48 PM

My thanks again demausdauth; this is exactly what I was looking for. I think that this is the solution I will use for now as it fits with the design I had in my head. I'll make use of the private variable and use the public properties to access it as you suggest (I hadn't considered that previously)

Once I have this out of the way I think I'll try the event-driven solution proposed by hawkvalley1 and see how the two compare.



Thanks both for taking the time to decipher my ramblings and reply.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1