Databinding to an image column in SQL Server 2000

Posts   
 
    
mhnyborg
User
Posts: 14
Joined: 26-Apr-2006
# Posted on: 21-Sep-2007 10:05:43   

I am binding to a LLBLGen Pro Entity with a Photo column (image type in the sql server. It is not working. It's something with the byte array.

I see the picture with the red cross in the .NET DataGridView

Error message from the GridGroupingControl from syncfusion

Unable to paste picture here

System.IndexOutOfRangeException: Index was outside the bounds of the array. at Syncfusion.Windows.Forms.ImageUtil.GetBitmapStream(Byte[] rawData) at Syncfusion.Windows.Forms.ImageUtil.ConvertToImage(Byte[] rawData) at Syncfusion.Windows.Forms.ImageUtil.ConvertToImage(Object value) at Syncfusion.Windows.Forms.Grid.GridImageCellRenderer.OnDraw(Graphics g, Rectangle clientRectangle, Int32 rowIndex, Int32 colIndex, GridStyleInfo style) at Syncfusion.Windows.Forms.Grid.GridCellRendererBase.Draw(Graphics g, Rectangle cellRectangle, Int32 rowIndex, Int32 colIndex, GridStyleInfo style) at Syncfusion.Windows.Forms.Grid.GridControlBase.OnDrawItem(Graphics g, Int32 rowIndex, Int32 colIndex, Rectangle rectItem, GridStyleInfo style)

DataGridView .NET

Unable to paste picture here

Any suggestions?

(removed address info, search engines can harvest in this forum. -- Otis)

Attachments
Filename File size Added on Approval
GridViewDotNet.png 39,392 21-Sep-2007 10:07.20 Approved
Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 21-Sep-2007 11:55:05   

I used V.S. 2005 I created a Windows Form with a dataGridView, a BindingSource and a Collection from a table which have an image field. I bound them all together and fetched the collection in Form_Load. I ran the application and the pictures were seen on the Grid.

My suggestion: You have SQL Server 2000, try what you did on Northwind and on Pubs databases Both have tables with images. But unfortunatly, Northwind was ported from Access database. The image fields (Employee.Photo) & (Category.Picture) don't contain a true image files; instead it contains the OLE object that Access builds to wrap any image. As a result, the stream of bytes you read from the field is prefixed with a header. You must strip off that header to get the true image bytes. Such a header is variable-length and also depends on the length of the originally imported file's name. For Northwind, the length of this offset is 78 bytes. If you insert other rows with Images, there would be no OLE Header.

mhnyborg
User
Posts: 14
Joined: 26-Apr-2006
# Posted on: 21-Sep-2007 12:34:56   

Thanks for the fast reply

Is it working with a empty table? that what I have. The TypeDefaultValue helper class returns new byte[0] for the image property.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 21-Sep-2007 13:07:31   

I see. So in case of an empty image, the .NET DataGridView shows the red cross image, which is the normal behaviour. And using another 3rd part grid control (syncfusion) it gives an exception. I think you shoud contact them about this issue.

mhnyborg
User
Posts: 14
Joined: 26-Apr-2006
# Posted on: 21-Sep-2007 15:22:35   

OK for the last time before you get tired of me flushed

I started from scratch again. Created the LLBLGen project and win project again. Added an EntityCollectionDataSource then a BindingSource. Set the BindingSource datasource to the EntityCollectionDataSource. Then a .NET DataGridView and set the datasource to the BindingSource. Its looks’ good at design time, but I get an error when I run the code. Se the attached picture for an error description

Attachments
Filename File size Added on Approval
GridViewDotNet.png 39,392 21-Sep-2007 15:23.28 Approved
Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 21-Sep-2007 18:08:42   

I reproduced it.

Having a null value for an image field ina database row, will cause the dataGridView to throw that exception.

Also, if you allow adding new rows to the dataGridView, and you clicked on the new last row the same exception will be thrown.

My first impression is that it's a dataGridView issue.

(EDIT) I attached the repro solution.

mhnyborg
User
Posts: 14
Joined: 26-Apr-2006
# Posted on: 22-Sep-2007 01:06:03   

OK I have created more test cases.

Its work with the dataset in VS2005 and with Linq2Sql in VS2008 beta 2. The grid is the .Net datagridview. There is no code only databinding

Please see the attachment for some screen dumps

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 22-Sep-2007 12:16:22   

It returns a default value of byte[0], which is an empty array. The datagridview crashes on that.

To overcome this, please set in the project properties in the llblgen pro designer the property 'ConvertNulledReferenceTypesToDefaultValue' to true. This makes a null value be returned as null instead of byte[0]. Could you check if that's indeed set to true in the project properties of your project (this value is inherited from the preferences).

Frans Bouma | Lead developer LLBLGen Pro
mhnyborg
User
Posts: 14
Joined: 26-Apr-2006
# Posted on: 23-Sep-2007 13:52:20   

First thanks for the great support, hope we find a solution to the problem.

ConvertNulledReferenceTypesToDefaultValue is set to true.

I am sending you a sql script to create the small test database I am working on. I have created it to test the ability to work with super types and subtype. A feature that really trills me.

I have a base product catalog table named ProductBaseAdv and to sub type tables named ProductAntenna and ProductNPlexer you can se the definition in the script file.

I hope you can find the time to set up a project and if it works send me the VS and LLBLGen Pro solution.

Attachments
Filename File size Added on Approval
CreateProductDatabase.sql 14,594 23-Sep-2007 13:52.32 Approved
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 24-Sep-2007 10:42:28   

Oh I see I made a mistake in my post! flushed . ConvertNulledReferenceTypesToDefaultValue should be false !

It's true by default, which means that every byte[] field returns byte[0] instead of null if it's null.

Also all string fields will then return "" instead of null if the field is null. So setting this to false in the project properties and re-generating the code has more impact than you might consider.

If you dont want to set this property to false because you want string fields to return "" when they're null instead of null, consider adding a new property to a partial class of the entity like this:


public byte[] ImageFieldToBind
{
    get 
   {
        if(this.ImageField.Length<=0)
        {
            return null;
        }
        else
        {
            return this.ImageField;
        }
    }
    set { this.ImageField = value; }
}

so it simply returns null if the image field is null. You then have to design your grid to exclude the ImageField column and keep the ImageFieldToBind column. simple_smile

Frans Bouma | Lead developer LLBLGen Pro
mhnyborg
User
Posts: 14
Joined: 26-Apr-2006
# Posted on: 24-Sep-2007 22:53:53   

Thanks just what the doctor ordered :-)

No I got a new problem, the EntityCollection component. How can I rebuild my DAL layer? And refresh the EntityCollection component in my toolbox without breaking all the databinding where I am using it? Any Suggesting?

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 25-Sep-2007 11:32:38   

How can I rebuild my DAL layer? And refresh the EntityCollection component in my toolbox without breaking all the databinding where I am using it? Any Suggesting?

Just rebuild everything and most probably nothing would break databinding. Unless you add new fields to your entities and you want them to appear in the bound control at design time. In this case set the datasource of the bound control to nothing, and the re-assign it again to the EntityCollection.