Replace System.Byte[] to System.Drawing.Image in generated code

Posts   
 
    
chungpn
User
Posts: 39
Joined: 23-Mar-2011
# Posted on: 22-Mar-2012 05:32:38   

I had successful implement a type converter to convert DB varbinary type to Image type in .net, but I must manual edit the generate code to replace System.Byte[] to System.Drawing.Image. Can I do this in the desinger?

the code llblgen genarate is:

public virtual System.Byte[] HinhAnh { get { return (System.Byte[])GetValue((int)NhanVienFieldIndex.HinhAnh, true); } set { SetValue((int)NhanVienFieldIndex.HinhAnh, value, true); } }

private void InitNhanVienEntityInfos()
    {


        this.AddElementFieldInfo("NhanVienEntity", "HinhAnh", typeof(**System.Byte[]**), false, false, false, true,  (int)NhanVienFieldIndex.HinhAnh, 2147483647, 0, 0);
        }

private void InitNhanVienEntityMappings()
    {

        this.AddElementFieldMapping( "NhanVienEntity", "HinhAnh", "HinhAnh", true, "VarBinary", 2147483647, 0, 0, false, "",  new **ImageByteConverter()**, typeof(**System.Byte[]**), 12 );
        }

but I want replace all System.Byte[] by System.Drawing.Image in the above code

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 22-Mar-2012 08:52:16   

Sure the TypeCoverter should be used in the Designer first, and then in code. Please check Type Conversion Definition Editor

chungpn
User
Posts: 39
Joined: 23-Mar-2011
# Posted on: 22-Mar-2012 09:39:58   

Yes, I have choosen my converter in Field Mappings tab, but the code generate like above .I want it is System.Drawing.Image , not System.Byte[]. How to achive this?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 22-Mar-2012 09:50:35   

So you should see "Image" as the .NET type of the field in the Designer, right?

chungpn
User
Posts: 39
Joined: 23-Mar-2011
# Posted on: 22-Mar-2012 09:51:38   

Yes, that Right

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 22-Mar-2012 09:54:18   

Strange, you hsould have the Image as the type in the generated code. Would you please regenerate the code into a new empty folder, and check the outcome.

chungpn
User
Posts: 39
Joined: 23-Mar-2011
# Posted on: 22-Mar-2012 10:54:24   

try regenerate stilll Not success Seem System.Drawing.Image not support in LLBLgen, I dont see this type in Type Shortcuts Otis, will you help me please.

this is my type converter:

using System; using System.Collections.Generic;

using System.Text; using System.ComponentModel; using System.Drawing; using System.IO;

namespace NTSoft.Helper.LLBLGen.TypeConverters {

public class ImageToByteConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {


        switch (sourceType.FullName)
        {
            case "System.Byte[]":
                return true;
            default:
                return false;
        }

    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {

        switch (destinationType.FullName)
        {
         case "System.Byte[]":
                return true;
            default:
                return false;
        }
    }

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


        if (value == null)
        {
            return null;
        }
        else
        {
            ImageConverter cnv = new ImageConverter();
            return (Image)cnv.ConvertFrom(value);
        }


    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if (value == null)
        {
            return null;
        }
        else
        {
            ImageConverter cnv = new ImageConverter();
            return (byte[])cnv.ConvertTo(value, Type.GetType("System.Byte[]"));
        }

    }

    public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
    {

        return new byte[0];
     // return new byte[1] {0};
        //return new byte[]{};

    }

}

}

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 23-Mar-2012 06:43:53   

We don't know yet what is your LLBLGen version. Anyway I reproduced it with all v3.x. There are two things to notice:

  1. The CreateInstance method should return the corresponding .Net type, that is an Image instance: public override object CreateInstance(ITypeDescriptorContext context,
System.Collections.IDictionary propertyValues)
{
    return new ImageConverter().CreateInstance(context, propertyValues);
}

That's why in LLBLGen Designer it looks valid if the field type is byte[] and the the rel.Type is byte[] as well. And that's why the type of the field is byte[] in the generated code. So, it should return an Image.

  1. Since you change that CreateInstance with an Image instance, the LLBLGen Designer doesn't load the typeConverter anymore. This could be, in my opinion, for two reasons:

2.1. The Designer can't resolve some dependencies of your converter, in this case that would be the System.Drawing.dll.

2.2. The return .net type of the converter (System.Drawing.Image) isn't recognized by LLBLGen Designer, so the converter is ignored.

I have to confirm what is going on on (2). I already discarded (2.1) because I added an import for System.Drawing and placed it on \ReferencedAssemblies on LLBLGen installation folder. I also load it on v3.5 (which now shows errors when loading TypeConverters in ApplicationOutput) and no errors were shown. So it seems, as you already guessed, that this could be because (2.2). I have to confirm that though.

I'm attached a solution to show the issue. To reproduce it: 1. Unzip the solution. 2. Build the \Code\TypeConverters\Tostil.TypeConverters.csproj project. 3. Place the built dll into \MyAdditionalTypeConverters folder. 4. Load the LLBLGen project into LLBLGen v3.1. Note that the TypeConverter is not loaded.

We are looking into this... In the meantime -and this maybe isn't ideal for you-, you can create a custom property in you entity class that converts the bytes[] field into a System.Drawing.Image.

Attachments
Filename File size Added on Approval
ImageConverter.zip 9,386 23-Mar-2012 06:44.08 Approved
David Elizondo | LLBLGen Support Team
chungpn
User
Posts: 39
Joined: 23-Mar-2011
# Posted on: 23-Mar-2012 07:59:21   

Can you give some code snippets use custom property to converts the bytes[] field into a System.Drawing.Image.

Thank you very much!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 23-Mar-2012 11:10:18   

@David: the type converter you posted returns an object with CreateInstance as it calls the TypeConverter class' CreateInstance. I'll see what it has to be. You also don't need a typeimport, as a type converter is loaded as a type converter.

@chungpn: please answer questions like which version you're using. thanks.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 23-Mar-2012 11:19:52   

The problem with David's example type converter is that it returns null when CreateInstance(null, null) is called on the type converter (as it's calling TypeConverter.CreateInstance() in the CreateInstance method). I'll change the type converter and see whether that works or not.

The problem of course is that Image is an abstract class. So it's not possible to create a real 'Image' instance as it's abstract. As there are 2 classes derived from Image, Bitmap and MetaFile, you could use Bitmap instead. Bitmap is the class in .NET which can contain any image file, be it .bmp, gif, png, jpg etc.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 23-Mar-2012 11:33:42   

Ok, to fix this do this: - in CreateInstance, do: return new Bitmap(10, 10);

  • compile your type converter dll and place it in a folder which is a valid type converter folder (either the main type converter folder or the folder specified as 'additional type converter folder' in the project settings/properties). important if you compile the type converter with .NET 4, run the designer also on .net 4 (v3.x)

  • load the project.

  • in 'Type shortcuts' (v3.1: right-click 'project node' and select 'edit type shortcuts'. v3.5: right-click project node and select 'settings' and then type shortcuts node), create a new type shortcut, for the Bitmap type which is available in the right dropdown box. E.g. specify 'image' as shortcut and the System.Drawing.Bitmap type as type.

  • In your entity, select the typeshortcut (e.g. 'image') you specified in type shortcuts as the type for the field which is now of type byte[].

  • in the mappings select the type converter on the fieldmapping as the types now don't match.

If you have many fields of type byte[] which should be images, use a type conversion definition.

Hope this helps. simple_smile

Frans Bouma | Lead developer LLBLGen Pro