Implementing Pointers in VB.NET?
-
I'm trying to get my Data Access classes to provide a Bind method to allow a member variable to be bound to a control, such as a textbox:
Customer.Bind( TextBox1, Customer.m_strUserName )
Inside the Bind method, I'm adding my own eventhandler to the control, and attempting to store the references to the control and the passed member variable into a collection, so this way many controls can be bound against the classes member variables:Public Sub Bind( ByRef ptrControl as System.Windows.Forms.TextBox, ByRef ptrMember as Object ) AddHandler ptrControl.KeyPress, AddressOf ConsumeKeyPress Dim ptrElement as new ControlCollectionGroup() ptrElement.ptrControl = ptrControl ptrElement.ptrMember = ptrMember.Clone() colControls.Add( ptrElement ) End Sub
Where the type being added into the collection is defined as:Structure ControlColelctionsGroup Public ptrElement as System.Windows.Forms.TextBox Public ptrMember as Object End Structure
Now the problem is to do with the references being passed for the control and member variable. When they are passed into Bind() as references, they work, and the code can access the original control and variable as you would expect. After this stage, when the references are passed to an element in a collection, or just stored within normal types within the class - the reference seems to disappear - and I get copies of the textbox and the member object instead. This then renders the whole thing useless as I need to be able to exchange data between the control and the member variable whenever a keypress takes place. So is there a most learned VB.NETter that can help me with these questions: 1. Can I reference a reference? 2. Is there something similar to StrPtr() I can use which was dropped after VB6. 3. Is there a better way of binding a control to a member variable? Thanks for reading this novel. -
I'm trying to get my Data Access classes to provide a Bind method to allow a member variable to be bound to a control, such as a textbox:
Customer.Bind( TextBox1, Customer.m_strUserName )
Inside the Bind method, I'm adding my own eventhandler to the control, and attempting to store the references to the control and the passed member variable into a collection, so this way many controls can be bound against the classes member variables:Public Sub Bind( ByRef ptrControl as System.Windows.Forms.TextBox, ByRef ptrMember as Object ) AddHandler ptrControl.KeyPress, AddressOf ConsumeKeyPress Dim ptrElement as new ControlCollectionGroup() ptrElement.ptrControl = ptrControl ptrElement.ptrMember = ptrMember.Clone() colControls.Add( ptrElement ) End Sub
Where the type being added into the collection is defined as:Structure ControlColelctionsGroup Public ptrElement as System.Windows.Forms.TextBox Public ptrMember as Object End Structure
Now the problem is to do with the references being passed for the control and member variable. When they are passed into Bind() as references, they work, and the code can access the original control and variable as you would expect. After this stage, when the references are passed to an element in a collection, or just stored within normal types within the class - the reference seems to disappear - and I get copies of the textbox and the member object instead. This then renders the whole thing useless as I need to be able to exchange data between the control and the member variable whenever a keypress takes place. So is there a most learned VB.NETter that can help me with these questions: 1. Can I reference a reference? 2. Is there something similar to StrPtr() I can use which was dropped after VB6. 3. Is there a better way of binding a control to a member variable? Thanks for reading this novel.TextBox
andObject
are reference types. You should pass a reference typeByVal
unless you need to change what the reference points to inside the called function. I can't think of a reason offhand. If you want to keep referring to the same object within your collection, you shouldn't useClone
. That's for making a copy of the remote object. This kind of thing is best dealt with using diagrams, unfortunately. I'll try with words. Say you callBind
like so:Bind( TextBox1, m_oData1 )
TextBox1
isn't actually the text box itself: it's just a reference to the text box. If, insideSub Bind
, you had the statement:ptrControl = TextBox2
the field
TextBox1
would now refer to the same control asTextBox2
. In your code, when you useptrElement.ptrMember = ptrMember.Clone()
that makes a new object which is a copy of the object referred to by
ptrMember
, then setsptrElement.ptrMember
to point to the new object. There's no link between this object and the originalptrMember
. I think your implementation will work if it looks more like:Public Sub Bind( ByVal ptrControl as System.Windows.Forms.TextBox, ByVal ptrMember as Object )
AddHandler ptrControl.KeyPress, AddressOf ConsumeKeyPress
Dim ptrElement As New ControlCollectionGroup()
ptrElement.ptrControl = ptrControl
ptrElement.ptrMember = ptrMembercolControls.Add( ptrElement )
End Sub
Hope this helps. Personally I find reference languages to be more, not less, confusing than languages with explicit pointers. I can follow explicit pointers because it's obvious - to me - what's happening.
-
TextBox
andObject
are reference types. You should pass a reference typeByVal
unless you need to change what the reference points to inside the called function. I can't think of a reason offhand. If you want to keep referring to the same object within your collection, you shouldn't useClone
. That's for making a copy of the remote object. This kind of thing is best dealt with using diagrams, unfortunately. I'll try with words. Say you callBind
like so:Bind( TextBox1, m_oData1 )
TextBox1
isn't actually the text box itself: it's just a reference to the text box. If, insideSub Bind
, you had the statement:ptrControl = TextBox2
the field
TextBox1
would now refer to the same control asTextBox2
. In your code, when you useptrElement.ptrMember = ptrMember.Clone()
that makes a new object which is a copy of the object referred to by
ptrMember
, then setsptrElement.ptrMember
to point to the new object. There's no link between this object and the originalptrMember
. I think your implementation will work if it looks more like:Public Sub Bind( ByVal ptrControl as System.Windows.Forms.TextBox, ByVal ptrMember as Object )
AddHandler ptrControl.KeyPress, AddressOf ConsumeKeyPress
Dim ptrElement As New ControlCollectionGroup()
ptrElement.ptrControl = ptrControl
ptrElement.ptrMember = ptrMembercolControls.Add( ptrElement )
End Sub
Hope this helps. Personally I find reference languages to be more, not less, confusing than languages with explicit pointers. I can follow explicit pointers because it's obvious - to me - what's happening.
Thanks for your suggestion, but unfortunately the references are still lost, and it would appear when the control and object are passed into the collection, they are passed copies. Sorry for leading you up the garden path by using that .Clone(), I was experimenting in the code - needless to say that didn't work. Anyhows, have implemented exactly what you specified, and the behaviour suggests that you cannot have a reference to a reference!!! In the good old days when I were but a young lad, and sweets were a penny each, and mobile phones were the size of a house, I could just use StrPtr(), but this feature has been ripped out of .NET...........:-(