mikesims10670
asked on
Best practices for managing multiple forms in VB.NET CF
I'm at a stand stil at the moment with an application I am developing under contract. Unfortunately I've run into a fairly serious native exception error that I'm having a helluva time debugging. I paid the cash for a Microsoft incident to help, but my support engineer won't be available until tomorrow morning. He took an initial look at my code and said the following:
-------------------------- ---------- ---------- ---------- ---------- --
Hi Mike,
I did a review of your code and I think I know what is happening, I’m just not quite sure why; I don’t think you should be able to do what you are code is doing:
The errant code is:
Private Sub btnBagDates_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBagDates.Click
Try
QuarterBagChange.CollectBa gChangeDat es()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Information, "btnBagDates_Click")
ExitApp(True)
End Try
End Sub
You can’t do that. QuarterBagChange is a Public Windows Form class and CollectBagChangeDates is an instance method, not a class (Shared) method. The instance method is referring to internal fields in the class, otherwise, it could be made Shared to make it a class method.
To use an instance method of an object, you have to instantiate the object and make calls via the instance. You haven’t created a new instance of QuarterBagChange. You need something like this:
Dim qbc as QuarterBagChange = New QuarterBagChange()
qbc.CollectBagChangeDates( )
But this is only the beginning of the problems: QuarterBagChange is actually a Windows Form which must have Show or ShowDialog called to display it and Dispose called to free it. BTW, Dispose on Windows Forms objects is NOT optional; Windows Forms in NETCF do not support finalizers so Dispose() must be called or you will leak native window objects.
I suspect some architectural work (like factoring out service functions from your forms and moving them into non-forms utility classes) will be needed to untangle your business requirements from the current forms hierarchy.
The reason I don’t know why you can do what you are doing is that it should not be possible to call an instance method without an instance variable; perhaps the rules for Visual Basic are looser than for C#. I know the C# compiler would choke on equivalent syntax. Please let me know if this resolves your issue.
-------------------------- ---------- ---------- ---------- ---------- --
He then updated with a new email that said:
-------------------------- ---------- ---------- ---------- ---------- --
P.S. I just realized why you didn’t get an error: VB.NET operates like VB 6.0 did – there is a hidden QuarterBagChange object created as soon as you reference QuarterBagChange and it is named QuarterBagChange. Unfortunately, this is fact is hidden from the VB programmer just as it was in VB 6 and in VB.NET it can wreak the havoc you are currently experiencing. You need to eliminate the hidden object by never using the class name to qualify an instance method call.
-------------------------- ---------- ---------- ---------- ---------- --
NOW ... what I need to see is VB.NET code that CORRECTLY handles multiple forms in the CF framework (2.0 on WM5). I have taken several courses in OOP, so I understand the concepts well. Unfortunately, however, my self taught knowledge in VB from the old days (5 and 6) have caused me to code in .NET the way I use to. So I am not accustomed to dealing with forms in any other way than I am now.
Should I somehow be using a publicly scoped set of routines and functions that essentially "puppet" the forms I created in the application? If so, how do I do this? Can anyone point me to some good examples?
Thank you,
Mike Sims
--------------------------
Hi Mike,
I did a review of your code and I think I know what is happening, I’m just not quite sure why; I don’t think you should be able to do what you are code is doing:
The errant code is:
Private Sub btnBagDates_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBagDates.Click
Try
QuarterBagChange.CollectBa
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Information, "btnBagDates_Click")
ExitApp(True)
End Try
End Sub
You can’t do that. QuarterBagChange is a Public Windows Form class and CollectBagChangeDates is an instance method, not a class (Shared) method. The instance method is referring to internal fields in the class, otherwise, it could be made Shared to make it a class method.
To use an instance method of an object, you have to instantiate the object and make calls via the instance. You haven’t created a new instance of QuarterBagChange. You need something like this:
Dim qbc as QuarterBagChange = New QuarterBagChange()
qbc.CollectBagChangeDates(
But this is only the beginning of the problems: QuarterBagChange is actually a Windows Form which must have Show or ShowDialog called to display it and Dispose called to free it. BTW, Dispose on Windows Forms objects is NOT optional; Windows Forms in NETCF do not support finalizers so Dispose() must be called or you will leak native window objects.
I suspect some architectural work (like factoring out service functions from your forms and moving them into non-forms utility classes) will be needed to untangle your business requirements from the current forms hierarchy.
The reason I don’t know why you can do what you are doing is that it should not be possible to call an instance method without an instance variable; perhaps the rules for Visual Basic are looser than for C#. I know the C# compiler would choke on equivalent syntax. Please let me know if this resolves your issue.
--------------------------
He then updated with a new email that said:
--------------------------
P.S. I just realized why you didn’t get an error: VB.NET operates like VB 6.0 did – there is a hidden QuarterBagChange object created as soon as you reference QuarterBagChange and it is named QuarterBagChange. Unfortunately, this is fact is hidden from the VB programmer just as it was in VB 6 and in VB.NET it can wreak the havoc you are currently experiencing. You need to eliminate the hidden object by never using the class name to qualify an instance method call.
--------------------------
NOW ... what I need to see is VB.NET code that CORRECTLY handles multiple forms in the CF framework (2.0 on WM5). I have taken several courses in OOP, so I understand the concepts well. Unfortunately, however, my self taught knowledge in VB from the old days (5 and 6) have caused me to code in .NET the way I use to. So I am not accustomed to dealing with forms in any other way than I am now.
Should I somehow be using a publicly scoped set of routines and functions that essentially "puppet" the forms I created in the application? If so, how do I do this? Can anyone point me to some good examples?
Thank you,
Mike Sims
is QuarterBagChange a form?
ASKER
Yes
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.