MCattle
MCattle

Reputation: 3167

Getting base field type when databinding to a Decimal (or Object) property

I've got a custom NumericEditor control that has a nullable Decimal property called Value. When I bind a data field to Value, I'd like to retrieve the underlying Type of the data that's bound, so that I can restrict the use of decimal places if the source field is an integral data type.

I figure I'd have to do this in the BindingContextChanged event, but how do I get the Type of the data field from the binding itself? My Google-Fu is failing me at the moment.

In short, I'm looking for something like the GetValueType method mentioned in the following question: Simple databinding - How to handle bound field/property change. Winforms, .Net

I imagine this method would also be handy if the Value property was an Object.

Upvotes: 2

Views: 599

Answers (2)

MCattle
MCattle

Reputation: 3167

I've come up with the following solution:

Private Sub NumericEditor_BindingContextChanged(sender As Object, e As EventArgs) Handles Me.BindingContextChanged
   If DataBindings.Count > 0 AndAlso DataBindings.Item("Value") IsNot Nothing Then
      Dim myPropDescs As PropertyDescriptorCollection = DataBindings.Item("Value").BindingManagerBase.GetItemProperties
      Dim propertyName As String = DataBindings.Item("Value").BindingMemberInfo.BindingField
      Dim bindingType As Type = myPropDescs.Find(propertyName, False).PropertyType

      Select Case bindingType
         Case GetType(SByte)
            DecimalPlaces = 0
            MinimumValue = SByte.MinValue
            MaximumValue = SByte.MaxValue
         Case GetType(Byte)
            DecimalPlaces = 0
            MinimumValue = Byte.MinValue
            MaximumValue = Byte.MaxValue
         Case GetType(Int16)
            DecimalPlaces = 0
            MinimumValue = Int16.MinValue
            MaximumValue = Int16.MaxValue
         Case GetType(UInt16)
            DecimalPlaces = 0
            MinimumValue = UInt16.MinValue
            MaximumValue = UInt16.MaxValue
         Case GetType(Int32)
            DecimalPlaces = 0
            MinimumValue = Int32.MinValue
            MaximumValue = Int32.MaxValue
         Case GetType(UInt32)
            DecimalPlaces = 0
            MinimumValue = UInt32.MinValue
            MaximumValue = UInt32.MaxValue
         Case GetType(Int64)
            DecimalPlaces = 0
            MinimumValue = Int64.MinValue
            MaximumValue = Int64.MaxValue
         Case GetType(UInt64)
            DecimalPlaces = 0
            MinimumValue = UInt64.MinValue
            MaximumValue = UInt64.MaxValue
         Case GetType(Single), GetType(Double), GetType(Decimal)
            MinimumValue = Decimal.MinValue
            MaximumValue = Decimal.MaxValue
      End Select
   End If
End Sub

It's a little repetitive and therefore not that elegant, but it works. (My actual code also has checks when setting MinimumValue and MaximumValue in case the developer has already set those properties, ensuring the developer's settings are not overridden if they are still valid.)

Upvotes: 0

Jirka Hanika
Jirka Hanika

Reputation: 13529

You will need to determine the binding context and navigate it, because there may be multiple bindings and you apparently are not getting information which one has changed. Something like this:

DirectCast(sender, Control).BindingContext.Item(dataSet, "dataMember").Bindings.Item(0).DataSource.GetType()

Upvotes: 0

Related Questions