Home
Help
Register
Log in

Search

 
   Active Threads  

You are here: Home > LLBLGen Pro > General> Here you go: Enum type converter example
 

Pages: 1
General
Here you go: Enum type converter example
Page:1/1 

  Print all messages in this thread  
Poster Message
alexdresko
User



Location:
Greenville, SC
Joined on:
08-Jun-2004 17:30:02
Posted:
336 posts
# Posted on: 24-Aug-2006 22:58:53.  
LLBLGen only comes with a boolean type converter, but I wanted to map one of my int database fields to an enum in my project.

The first thing I did was create a new class library project in my solution and set the output directory of this project to be "C:\Program Files\Solutions Design\LLBLGen Pro v2.0\TypeConverters"

The main application project already contained the following enum (I renamed the namespaces, types and values to be more generic for this example. You will obviously want to replace YourNamespace and YourEnumType with more appropriate values):

Code:

namespace YourNamespace
{
    public enum YourEnumType: int
    {
        ADefaultValue = 0,
        AnotherValue = 1,
        YouGetTheIdea = 2
    }
}


To make this enum available to the type converter, you should add a reference from the main application project to the type converter project. (Truthfully, I don't actually know if adding this reference will work becasue I'm working on an ASP.NET v2 project and therefore can't make this reference... for the time being, I moved the enum above to my type converter project)

I then added a new class to the type converter project with the following code:

Code:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace YourNamespace.TypeConverters
{

    public class YourTypeConverter : TypeConverter
    {
        public YourTypeConverter ()
        {
        }

        public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType )
        {
            switch ( sourceType.FullName )
            {
                case "System.Int32":
                case "System.Int16":
                    return true;
                default:
                    return false;
            }
        }

        public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType )
        {
            switch ( destinationType.FullName )
            {
                case "System.Int32":
                case "System.Int16":
                    return true;
                default:
                    return false;
            }
        }

        public override object ConvertFrom( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value )
        {
            YourNamespace.YourEnumType yourEnum = YourNamespace.YourEnumType.ADefaultValue;
                    

            switch ( value.GetType().FullName )
            {
                case "System.Int32":
                case "System.Int16":
                    yourEnum = (YourNamespace.YourEnumType)Enum.ToObject( typeof( YourNamespace.YourEnumType), (int)value );
                    break;
                default:
                    throw new NotSupportedException( "Conversion from a value of type '" + value.GetType().ToString() + "' to YourNamespace.YourEnumType isn't supported" );
            }

            return status;
        }

        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 is YourNamespace.YourEnumType) )
            {
                throw new ArgumentException( "Value isn't of type YourNamespace.YourEnumType", "value" );
            }

            YourNamespace.YourEnumType yourEnum = (YourNamespace.YourEnumType)value;

            switch ( destinationType.FullName )
            {
                case "System.Int32":
                    return (int)yourEnum;
                case "System.Int16":
                    return (short)yourEnum;
                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 YourNamespace.YourEnumType.ADefaultValue;
        }

    }
}


Now, make sure LLBLGen is shutdown and compile your solution. If successful, you should be able to open LLBLGen again and set any of your int fields to use the type converter. To do this, right click on an entity in LLBLGen and select "Edit / Properties". Then, on the "Mapped entity fields" tab, select a field and look below for the "Use different .NET type" drop down list. This drop down list should contain an entry for your type converter. Select it and press the "Set" button.

Generate that sucker and switch back to your VS solution. To make everything work right, you've got to add a reference from your type converter project to both your DatabaseSpecific and DatabaseGeneric projects (Note, I'm using the adapter framework in my solution and both the specific and generic projects are part of my solution.)

That's it! You should be able to compile the your LLBLGen projects again and use your entities with the enum attached to them. It works great and was easy to do! In fact, it took three times longer to write this post than it did to create and test the type converter!

Have fun and let me know if you run into any problems. I wrote most of this from memory after I finished, so it's possible I forgot something.



I'm not a player, I just code a lot.   Top
bclubb
User



Location:
Norman, Oklahoma
Joined on:
12-Feb-2004 22:18:04
Posted:
934 posts
# Posted on: 25-Aug-2006 02:59:16.  
Thanks for the contribuition. This is definately a functionality that many people have inquired about since type converters were introduced.

  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
34706 posts
# Posted on: 25-Aug-2006 10:56:09.  
Cool contribution, Alex! Laugh
Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
Kris
User



Location:
the Netherlands
Joined on:
27-Oct-2005 20:48:11
Posted:
79 posts
# Posted on: 25-Aug-2006 16:27:59.  
Nice contribution. I'm gonna use this one. Wink


 
Top
alexdresko
User



Location:
Greenville, SC
Joined on:
08-Jun-2004 17:30:02
Posted:
336 posts
# Posted on: 25-Aug-2006 17:13:55.  
Awww shucks.. it's only like 50 lines of code that's mostly copy/pasted from the boolean type converter sample. Regular Smiley
I'm not a player, I just code a lot.   Top
alexdresko
User



Location:
Greenville, SC
Joined on:
08-Jun-2004 17:30:02
Posted:
336 posts
# Posted on: 25-Aug-2006 19:24:06.  
Fixed a small typo I introduced while converting the type and variable names..

I'm not a player, I just code a lot.   Top
jspanocsi
User



Location:

Joined on:
04-Mar-2005 20:48:51
Posted:
145 posts
# Posted on: 25-Aug-2006 20:55:28.  
I implemented this for a field in my app. It's works great, except it killed 2 way databinding. It only works one way now (entity to combo box) but when you pick something else in the combo and tab off, it goes back to what it was. Any ideas on how to fix that?

Thanks!
  Top
alexdresko
User



Location:
Greenville, SC
Joined on:
08-Jun-2004 17:30:02
Posted:
336 posts
# Posted on: 25-Aug-2006 21:16:49.  
jspanocsi wrote:
I implemented this for a field in my app. It's works great, except it killed 2 way databinding. It only works one way now (entity to combo box) but when you pick something else in the combo and tab off, it goes back to what it was. Any ideas on how to fix that?

Thanks!

Frans, for the record, jspanocsi in the next cubicle over from me so this is a question for you.


I'm not a player, I just code a lot.   Top
jarod725
User



Location:
Jackson, MS
Joined on:
18-Jan-2007 16:52:24
Posted:
2 posts
# Posted on: 18-Jan-2007 16:56:55.  
Fyi, it appears that you also need to direct the output of the project containing the enum definition to %LLBL-InstallDir%/TypeConverters. This was moot in your case since your enum was packaged with the converter. Wink
  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
34706 posts
# Posted on: 20-Jan-2007 00:51:36.  
jarod725 wrote:
Fyi, it appears that you also need to direct the output of the project containing the enum definition to %LLBL-InstallDir%/TypeConverters. This was moot in your case since your enum was packaged with the converter. Wink

Could you explain that a bit please?


Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
davidsidlinger
User



Location:
Nashville, TN, USA
Joined on:
12-Mar-2007 18:23:59
Posted:
17 posts
# Posted on: 08-Jul-2008 21:21:55.  
How about this one? It works for any enumeration, you just need to declare a type like so:

Code:
public class MyEnumConverter : EnumerationConverter<MyEnum> {}


Code:

    public abstract class EnumerationConverter<T> : TypeConverter
    {
        private readonly IList<Type> _validTypes = new[] {typeof(byte), typeof(short), typeof(int), typeof(long)};

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == null)
            {
                throw new ArgumentNullException("sourceType");
            }

            return _validTypes.Contains(sourceType);
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == null)
            {
                throw new ArgumentNullException("destinationType");
            }
            return _validTypes.Contains(destinationType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (_validTypes.Contains(value.GetType()))
            {
                return Enum.ToObject(typeof(T), value);
            }
            throw new NotSupportedException();
        }

        public override object ConvertTo(ITypeDescriptorContext context,
                                         CultureInfo culture,
                                         object value,
                                         Type destinationType)
        {
            if (destinationType == null)
            {
                throw new ArgumentNullException("destinationType");
            }
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            Debug.Assert(value is T);
            return Convert.ChangeType(value, destinationType, culture ?? CultureInfo.InvariantCulture);
        }

        public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
        {
            return default(T);
        }
    }


Requires .NET 3.5/C# 3.0 (someone may be willing to make a version compatible with 2.0).
  Top
edalzell
User



Location:

Joined on:
27-May-2008 02:17:53
Posted:
44 posts
# Posted on: 25-May-2009 21:52:07.  
Removed by head-in-the-clouds-poster

  Top
Pages: 1  


Powered by HnD ©2002-2007 Solutions Design
HnD uses LLBLGen Pro

Version: 2.1.12172008 Final.