Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Greg, So far, the error has nothing to do with setting values to the created new row. When using BO.NewRow() SF will populate it with the default values which are good enough in my case. In order to make it work I added a "New" command to initialize the Private BO variable like this: Private _insuranceCompany As New InsuranceCompanyBOThen I made some changes to the property code to make sure the BO is filled all the time, like this: Public ReadOnly Property [InsuranceCompany]() As InsuranceCompanyBO Get '-- If the private BO has not been created, then create it here. If _insuranceCompany Is Nothing Then Dim _insuranceCompany As New InsuranceCompanyBO End If If Not String.IsNullOrEmpty(Me.FK_InsuranceCompany) Then _insuranceCompany.FillByPrimaryKey( Me.FK_InsuranceCompany) End If '-- Check if the BO is empty... '-- Initiailize a new row, default values could be added here if needed. If _insuranceCompany.Count = 0 Then _insuranceCompany.NewRow() '-- AcceptChanges on the table, so it isn't dirty (but doesn't save anything to the database) _insuranceCompany.CurrentDataTable.AcceptChanges() End If Return _insuranceCompany End GetEnd Property So far the code above is working fine.
Edhy Rijo
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
When you call new row, I think is just adds a new row to the data table, with the values being set to whatever is the default for their type. For strings, that is Nothing (null), hence the error. Don't forget the other part of the code, which is to set values of that new row: _insuranceCompany.InsuranceCompanyName = String.Empty
...etc. Do this right after you call NewRow()
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Humm, This is getting better when changing the code as follow: Private _insuranceCompany As InsuranceCompanyBO '--This is at the top of the classPublic ReadOnly Property [InsuranceCompany]() As InsuranceCompanyBO Get If _insuranceCompany Is Nothing Then Dim _insuranceCompany As New InsuranceCompanyBO If Not String.IsNullOrEmpty(Me.FK_InsuranceCompany) Then _insuranceCompany.FillByPrimaryKey( Me.FK_InsuranceCompany) End If '-- Check if the BO is empty... If _insuranceCompany.Count = 0 Then '-- Initiailize a row with appropriate values _insuranceCompany.NewRow() End If End If Return _insuranceCompany End GetEnd PropertyI now get an error when trying to use this property in a code like this: Dim x As String = Me.PolicyBO1.InsuranceCompany.CompanyNameLook at the attached image for the error: NullReferenceException was unhandled by user code. Object reference not set to an instance of an object. What I understand about this error is that I would need to create an instance of this object in order to use this property, while when using the original method there was not need to do that, guess because previous method was always creating an instance of the class with this code: Dim loLookupBO As New InsuranceCompanyBO
Edhy Rijo
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
Yep, I think the adding the blank row would be very easy. First you call NewRow on the BO, which adds a new row based on the table's schema: bo.NewRow() Then you just set the properties: bo.InsuranceCompanyName = "None" bo.InsuranceCompanyAddress = String.Empty etc. Finally, I'd call AcceptChanges on the table, so it isn't dirty (but doesn't save anything to the database): bo.CurrentDataTable.AcceptChanges() Easy peasy I agree that it is amazing how little code is often needed. Initially I spent something like a 10:1 ratio between learning and coding. Often I'd spend a couple of hours to realize it was one line of code!
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Hi Greg, Bill, Third, on you question about what to do if the BO is empty and having to test it, why not just test it in the property and add the row there? You could initialize the data in that row with values that makes sense when there is no data in the BO. Thanks, the code is pretty understandable. About the third option, this where a function like SCATTER MEMVAR BLANK would do the trick on initializing the empty row, unless I am just missing the simple point on using the BO.NewRow() to have a blank row with no values, so any use of its property will not throw an error. I will test that. Also thanks for the points about not using the descriptors, you are right and these are not needed for this kind of properties. All the time I simply get amazed with how functionality that seems pretty difficult or hard to do are accomplish in the .NET world and of course SF with a couple of line of code.
Edhy Rijo
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
Sigh...It fubarred my code . I didn't use html codes...In any case, I hope this is enough to keep you moving!
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
A couple of thoughts... First, I don't think you need to make this a custom field property, with all the attributes. Those are needed if you want to bind the property to a control. I doubt that you will bind a BO to the property of a control. So just a normal, public property should work. Second, you are creating and filling this BO every time you access the property. You probably want to think about caching it in a private and only creating it the first time. Third, on you question about what to do if the BO is empty and having to test it, why not just test it in the property and add the row there? You could initialize the data in that row with values that makes sense when there is no data in the BO. Something like: ' This holds the value locally, so you don't have to keep recreating it
Private _insuranceCompany As InsuranceCompanyBO
'''
''' Returns an instance of the InsuranceCompanyBO
''' filled with data from the current parent record.
'''
'''
'''
'''
_
Public ReadOnly Property [InsuranceCompany]() As InsuranceCompanyBO
Get
If _insuranceCompany Is Nothing Then
Dim _insuranceCompany As New InsuranceCompanyBO
If Not String.IsNullOrEmpty(Me.FK_InsuranceCompany) Then
_insuranceCompany.FillByPrimaryKey(Me.FK_InsuranceCompany)
End If
'-- Check if the BO is empty...
If _insuranceCompany.Count = 0 Then
'-- Initiailize a row with appropriate values
End If
End If
Return loLookupBO
End Get
End Property That is how I'd start in any case, plus using some of Paul's suggestions to keep parent/child BOs in synch.
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
I am sure, there should be something I could add to the property code to avoid having to keep testing for the Me.PolicyBO1.InsuranceCompany.Count Thinking about that, is there a way to have something like the VFP command SCATTER MEMVAR BLANK? that way I could test for the BO.count in the ParentBO and if count = 0, just create a new empty row. What do you think about it?
Edhy Rijo
|
|
|
Bill Cunnien
|
|
Group: Forum Members
Posts: 785,
Visits: 3.6K
|
This stuff sure is fun!! Glad it is working for you...I'll keep my eyes pealed (peeled?) here in case someone does offer a better way of handling this. Have a great weekend! Bill
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Well, here the working version of my code ''' <summary>''' Returns an instance of the InsuranceCompanyBO''' filled with data from the current parent record.''' </summary>''' <value></value>''' <returns></returns>''' <remarks></remarks><Browsable( False), _BusinessFieldDisplayInEditor(), _ Description( "Insurance Company"), _DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _ Public ReadOnly Property [InsuranceCompany]() As InsuranceCompanyBO Get Dim loLookupBO As New InsuranceCompanyBO If Not String.IsNullOrEmpty(Me.FK_InsuranceCompany) Then loLookupBO.FillByPrimaryKey( Me.FK_InsuranceCompany) End If Return loLookupBO End GetEnd Property And I added this property to my Function GetCustomBindablePropertyDescriptors(). It was really easy, even though during a debug session I can not really see any property of the PolicyBO.InsuranceCompany object, I would get something like this in the watch window: Me.PolicyBO1.InsuranceCompany.Count Evaluation of expression or statement timed out.
Also I have to be careful when to use any property of that object since it may not have any data and would throw errors, so I do this: If Me.PolicyBO1.InsuranceCompany.Count Then Dim x As String = Me.PolicyBO1.InsuranceCompany.CompanyName If Not String.IsNullOrEmpty(x) Then MessageBox.Show(x) End IfEnd If
I am sure, there should be something I could add to the property code to avoid having to keep testing for the Me.PolicyBO1.InsuranceCompany.Count Thanks again to all of you for pointing me to the right path and if there is a way to improve this, please do not hesitate to let me know.
Edhy Rijo
|
|
|