Binding to a Custom Field


Author
Message
Larry Caylor
Larry Caylor
Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)
Group: Awaiting Activation
Posts: 592, Visits: 3.7K

Is it possible to create a custom field in a BO, that is not part of the underlying DataSource,  that I can bind to?  I tried adding the following custom field to my BO.

 

Private mVerifyPassword As String = ""

 

<Browsable(False), _

BusinessFieldDisplayInEditor(), _

Description("Verify Password"), _

DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _

Public Property UserCF_VerifyPassword() As System.String

   Get

     Return mVerifyPassword

   End Get

   Set(ByVal value As System.String)

      If mVerifyPassword = value.Trim Then Exit Property

      mVerifyPassword = value.Trim

Me.OnFieldPropertyChanged(Me, _

 New UserFieldChangedEventArgsmVerifyPassword))

   End Set

End Property

 

I can bind to it in the designer but when I go to run the program I get the following error:

 

BusinessLayerException

                An error occurred while refreshing the data from field 'UserBO.UserCF_VerifyPassword' to property 'Text' on control 'txtVerifyPassword.'  Are you missing FieldPropertyDescriptor for a custom property?

ArgumentException

                Cannot bind to the property or column UserCF_VerifyPassword on the DataSource.

Parameter name: dataMember

 

Source     : MicroFour StrataFrame Business

 

Stack Trace:

   at System.Windows.Forms.BindToObject.CheckBinding()

   at System.Windows.Forms.BindToObject.SetBindingManagerBase(BindingManagerBase lManager)

   at System.Windows.Forms.Binding.SetListManager(BindingManagerBase bindingManagerBase)

   at System.Windows.Forms.ListManagerBindingsCollection.AddCore(Binding dataBinding)

   at System.Windows.Forms.BindingsCollection.Add(Binding binding) ...

 

-Larry

Larry Caylor
Larry Caylor
Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)
Group: Awaiting Activation
Posts: 592, Visits: 3.7K

I should have mentioned in my previous post that the custom field that I want to bind to is not ReadOnly. Binding of ReadOnly custom fields as shown in the getting started guide works fine.

 

I finally figured out that in order to get two way binding I needed to add a FieldPropertyDescriptor object for the custom field and add it to the PropertyDiscriptorDictionary.  What I’m not sure of at this point is what other dictionaries I need to add the field to since I’m not sure how and where each one is used.

 

-Larry

StrataFrame Team
S
StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
That's the only dictionary that you need to add the FieldPropertyDescriptor to. The reason the field PropertyDescriptorDictionary is used is because without them, the binding slows down considerably because .NET uses reflection to evaluate the properties.



The new tutorial has a sample on how to add the FieldPropertyDescriptor to the dictionary. The dictionary is shared (static) so you only need to add it once, not every time a new instance of your bo is created. The best thing to do is overload the GetCustomFieldPropertyDescriptors() method and return a new instance of your descriptor. This overload will only be called the first time an instance of your business object is created, so you don't have to worry about ending up with multiple copies of the same field descriptor in the dictionary.



Kudos on figuring that out, though Smile
Larry Caylor
Larry Caylor
Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)
Group: Awaiting Activation
Posts: 592, Visits: 3.7K

In the documentation an example is provided for creating a custom property descriptor using ReflectionPropertyDescriptor(). However the doc says for a real-world application you should create your own class. Can you provide an example or documentation describing what actually must be in a custom field descriptor class? 

-Larry

Trent Taylor
Trent Taylor
StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)StrataFrame Developer (8.7K reputation)
Group: StrataFrame Developers
Posts: 6.6K, Visits: 6.9K
Larry,

You can create your own class if you need to do some more sophisticated processing and I will show you an example of that, but to do eveything youa re attempting to do you can use a ReflectionpropertyDescriptor and place code similar to this in your business object:

Recommend Solution for your Situation

''' <summary>
''' Specify the custom property descriptors
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Protected Overrides Function GetCustomBindablePropertyDescriptors() As MicroFour.StrataFrame.Business.FieldPropertyDescriptor()

'-- Create and return a new array of FieldPropertyDescriptor
' objects that contains the ReflectionPropertyDescriptor
' for the UserCF_VerifyPassword field.
Return New MicroFour.StrataFrame.Business.FieldPropertyDescriptor() { _
New MicroFour.StrataFrame.Business.ReflectionPropertyDescriptor("UserCF_VerifyPassword", GetType(YourBO)), _
New MicroFour.StrataFrame.Business.ReflectionPropertyDescriptor("YourNextCustomField", GetType(UsersBO))}

End Function

Creating a Custom Class

To create a custom class it would look something like this which is what we do through the BO Mapper when the field is not custom or overwritten with custom code.

''' <summary>
''' A PropertyDescriptor class used to Get and Set the value of the UserCF_VerifyPassword property.
''' </summary>
''' <remarks></remarks>
Private Class UserCF_VerifyPassword_Descriptor
    Inherits MicroFour.StrataFrame.Business.FieldPropertyDescriptor

Public
Sub New()
     MyBase.New("UserCF_VerifyPassword")
End Sub

Private _PropertyType As System.Type = GetType(System.String)

Public Overrides Function GetValue(ByVal component As Object) As Object
   
Return CType(component, YourBO).UserCF_VerifyPassword
End Function

Public Overrides Sub SetValue(ByVal component As Object, ByVal Value As Object)
   
CType(component, YourBO).UserCF_VerifyPassword = CType(Value, System.String)
End Sub

Public Overrides ReadOnly Property PropertyType() As System.Type
   
Get
        Return Me._PropertyType
   
End Get
End Property

Public Overrides ReadOnly Property ComponentType() As System.Type
   
Get
       
Return _ComponentType
    
End Get
End Property

End Class

Once the class is created, you still need to overwrite the GetCustomBindablePropertyDescriptors() method add return the collection including your new class:

Return New MicroFour.StrataFrame.Business.FieldPropertyDescriptor() { _
New UserCF_VerifyPassword_Descriptor(), _
New MicroFour.StrataFrame.Business.ReflectionPropertyDescriptor("YourNextCustomField", GetType(UsersBO))}


StrataFrame Team
S
StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
You can always start by copying one of the descriptor classes from the .designer.cs (or .designer.vb) file and go from there. Within the class, you will only need to change your _PropertyType value to the return type of the property and change the Get and Set methods to get and return the proper property respectively. And you'll also need to change the name of the class Smile And then, just like Trent said, make sure you return the value as part of the collection returned from the GetCustomBindablePropertyDescriptors() method.
Larry Caylor
Larry Caylor
Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)Advanced StrataFrame User (902 reputation)
Group: Awaiting Activation
Posts: 592, Visits: 3.7K
Ben, Trent,

Thanks for the help. Copying and modifying the code from the designer file makes it real easy.

-Larry

StrataFrame Team
S
StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)StrataFrame Developer (3.5K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
That's what we're here for Smile
GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Similar Topics

Reading This Topic

Login

Explore
Messages
Mentions
Search