views:

307

answers:

1

So hopefully this is a silly question (that would make it easily answered).

I'm trying to make a composite server control that encapsulates a TextBox, some validators and other stuff, depending on the type of field required.

My control has a "DataType" value that lets me determine what to display. For example if DataType is "Date" I render a AjaxControlToolkit.CalendarExtender, etc.

My generic "Value" property is an object and will return whatever the DataType property calls for, so in the above example the Value would be a Date type.

So here's my problem, I need to convert my incoming Value property to whatever the DataType calls for at runtime.

As you can see I attempted to write a TypeConverter for it but it doesn't seem to work, I end up with this error during compile:

Unable to generate code for a value of type 'System.Object'. This error occurred while trying to generate the property value for Value.

Any help would be much appreciated!

Here is how I'm attempting to call my control:

<custom:SomeTextControl ID="dateFoo" runat="server" DataType="Date" Value="08/11/2009" />

Here is my class:

Public Class SomeTextControl
Inherits Control

  Private _Value as Object
  <Bindable(True), TypeConverter(GetType(ObjectConverter))> _
  Public Property Value() As Object
    Get
        Return _Value
    End Get
    Set(ByVal value As Object)
        _Value = value
    End Set
  End Property
End Class

Public Class ObjectConverter
    Inherits TypeConverter

    Public Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
        Dim o As Object
        o = value
        Return o
    End Function

    Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
        If sourceType Is GetType(String) Then
            Return True
        End If
        Return MyBase.CanConvertFrom(context, sourceType)
    End Function

    Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
        If destinationType Is GetType(String) Then
            Return True
        End If
        Return MyBase.CanConvertTo(context, destinationType)
    End Function
End Class
A: 

So seems that I semi figured it out myself... so much for overzealously asking questions.

Anyway, seems I had forgotten to check if the destinationType is a InstanceDescriptor (duh). Once I got that it was a few more mins to figure out I had to set my Object to a String (or something else, but I'm opting for a String since I'm just going to spit it back out into a TextBox anyway) since an Object doesn't take a constructor.

Let me know if you guys have any better ideas.

So I ended up with this TypeConverter:

Friend Class ObjectConverter
    Inherits TypeConverter

    Public Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
        Return value
    End Function

    Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
        If sourceType Is GetType(String) Then
            Return True
        ElseIf sourceType Is GetType(InstanceDescriptor) Then
            Return True
        End If
        Return MyBase.CanConvertFrom(context, sourceType)
    End Function

    Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
        If destinationType Is GetType(String) Then
            Return True
        ElseIf destinationType Is GetType(InstanceDescriptor) Then
            Return True
        End If
        Return MyBase.CanConvertTo(context, destinationType)
    End Function

    Public Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As System.Type) As Object
        If destinationType Is GetType(InstanceDescriptor) Then
            Dim constructor As ConstructorInfo = GetType(String).GetConstructor(New Type() {GetType(Char())})
            Dim instance As New InstanceDescriptor(constructor, New Object() {CType(value.ToString, Char())})
            Return instance
        End If

        Return MyBase.ConvertTo(context, culture, value, destinationType)
    End Function
End Class
aforty