TypeConverter Problem

Posts   
 
    
Wade
User
Posts: 76
Joined: 15-Jun-2004
# Posted on: 13-Jun-2008 15:24:14   

I am trying to create a type converter to convert a SQL Server bit DB Field to a Char for UI purposes. Also, I am using LLBLGen 2.5. It does not work, I am still getting Boolean as the data type. Here is the code:


using System;
using System.ComponentModel;


namespace BitCharacterTypeConverter
{
    [Description("Converter with as core type System.Char, for mapping a field with a .NET type System.Char onto a bit database field")]
    public class BitCharacterTypeConverter : TypeConverter
    {

        #region Constructor

        public BitCharacterTypeConverter()
        {
        }

        #endregion


        #region Public Methods

        public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
        {
            return true;
        }


        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            // any bit/boolean type is accepted.
            switch (sourceType.FullName)
            {
                case "System.Boolean":
                    return true;
                default:
                    return false;
            }
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            // any bit/boolean type is accepted. 
            switch (destinationType.FullName)
            {
                case "System.Boolean":
                    return true;
                default:
                    return false;
            }
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {

            char toReturn = ' ';
            switch (value.GetType().FullName)
            {
                case "System.Boolean":
                    toReturn = 'X';
                    break;
                default:
                    throw new NotSupportedException("Conversion from a value of type '" + value.GetType().ToString() + "' to System.Char isn't supported");
            }

            return toReturn;
        }

        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", "Value can't be null");
            }

            if ( value.GetType().FullName != "System.Char" )
            {
                throw new ArgumentException("Value isn't of type char", "value");
            }

            if ( Convert.ToChar(value) == 'X' )
            {
                switch (destinationType.FullName)
                {
                    case "System.Boolean":
                        return true;
                    default:
                        throw new NotSupportedException("Conversion to a value of type '" + destinationType.ToString() + "' isn't supported");
                }
            }
            else
            {
                switch (destinationType.FullName)
                {
                    case "System.Boolean":
                        return false;
                    default:
                        throw new NotSupportedException("Conversion to a value of type '" + destinationType.ToString() + "' isn't supported");
                }
            }
        }


        #endregion
    }
}

Does this look right?

Thanks, Wade

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 13-Jun-2008 15:44:42   

I understand from your words that field was still generated in code with type boolean.

Did you set the field to use the specified TypeConverter from the LLBLGen Pro Designer?

Wade
User
Posts: 76
Joined: 15-Jun-2004
# Posted on: 13-Jun-2008 17:34:00   

Yes, but it did not change the generated code.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 14-Jun-2008 08:01:04   

Just to be sure, please double check you follow these steps:

  1. Compile your TypeConverter project.
  2. Copy the built assembly to _[LLBLGen Pro v2.5 IntstallationFolder]\TypeConverters\ _or to your custom folder (if you set the _AdditionalTypeConverterFolder _at Project properties).
  3. Open your project, locate the interested entity and entity field and set the field to use the specified TypeConverter (you click "Set" button. ¿What .Net type is the field now at LLBLGenPro Designer?
  4. Generate code.
David Elizondo | LLBLGen Support Team
Wade
User
Posts: 76
Joined: 15-Jun-2004
# Posted on: 17-Jun-2008 16:20:47   

I got it to work. It turned out to be a problem with the Type Converter Code itself. In the CreateInstance Method I was returning a boolean true and not a Character data type. Here is the code that works in case someone would like it for a reference:


using System;
using System.ComponentModel;


namespace SD.LLBLGen.Pro.TypeConverters
{
    [Description("Converter with as core type System.Char, for mapping a field with a .NET type System.Char onto a bit database field")]
    public class BitCharacterTypeConverter : TypeConverter
    {

        #region Constructor

        public BitCharacterTypeConverter()
        {
        }

        #endregion


        #region Public Methods

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            // any bit/boolean type is accepted.
            switch (sourceType.FullName)
            {
                case "System.Boolean":
                    return true;
                default:
                    return false;
            }
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            // any bit/boolean type is accepted. 
            switch (destinationType.FullName)
            {
                case "System.Boolean":
                    return true;
                default:
                    return false;
            }
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {

            char toReturn = ' ';
            switch (value.GetType().FullName)
            {
                case "System.Boolean":
                    if (Convert.ToBoolean(value))
                    {
                        toReturn = 'X';
                    }
                    break;
                default:
                    throw new NotSupportedException("Conversion from a value of type '" + value.GetType().ToString() + "' to System.Char isn't supported");
            }

            return toReturn;
        }

        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value", "Value can't be null");
            }

            //if ( value.GetType().FullName != "System.Char" )
            //{
            //  throw new ArgumentException("Value isn't of type char", "value");
            //}

            if ( Convert.ToChar(value) == 'X' )
            {
                switch (destinationType.FullName)
                {
                    case "System.Boolean":
                        return true;
                    default:
                        throw new NotSupportedException("Conversion to a value of type '" + destinationType.ToString() + "' isn't supported");
                }
            }
            else
            {
                switch (destinationType.FullName)
                {
                    case "System.Boolean":
                        return false;
                    default:
                        throw new NotSupportedException("Conversion to a value of type '" + destinationType.ToString() + "' isn't supported");
                }
            }
        }


        public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
        {
            return ' ';
        }


        #endregion
    }
}

Wade
User
Posts: 76
Joined: 15-Jun-2004
# Posted on: 20-Jun-2008 05:46:29   

For what it is worth: After spending several hours getting the type converter figured out and working, I realized the quickest way to do what I needed was to go into the generated Entity before usage of a type converter. Then go to the bottom of the source code and create an additional public property with the datatype I needed for the UI and have the Setters and Getters manage the LLBLGen generated properties in the Custom Code section. It works perfectly, does not get overwritten with new generation of the LLBLGen Entities, and is quick!

Just in case someone else goes down this path, I thought I would post and let you know what I did.