2

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.

Community
  • 1
  • 1
MCattle
  • 2,897
  • 2
  • 38
  • 54

2 Answers2

0

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()
Jirka Hanika
  • 13,301
  • 3
  • 46
  • 75
  • That's the direction I've been going in, but since this is in a custom control, it doesn't know what the data source is. I believe the answer is with `Me.DataBindings.Item("Value").BindingManagerBase.GetItemProperties`, but I haven't been able to move further from there. – MCattle May 29 '12 at 14:32
0

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.)

MCattle
  • 2,897
  • 2
  • 38
  • 54