Image Thumbnail Refresh ProblemImage Thumbnail Refresh Problem
Old forum URL: forums.lhotka.net/forums/t/4260.aspx
dufflepud posted on Wednesday, January 30, 2008
I am having a problem with a bound thumbnail image not refreshing in a datagridview column. I am allowing the user to double click the thumbnail to pull up a little drawing window. After they draw I assign the bitmap to the BO property. I also need the thumbnail image to update on the grid. No matter what I do the thumbnail returns the same image it initially had. It seems to be caching it and not getting the updated image. Here is the code from the BO class:
Public Property Sketch() As Drawing.Bitmap
Get
CanReadProperty("Sketch", True)
Return _sketch
End Get
Set(ByVal value As Drawing.Bitmap)
CanWriteProperty("Sketch", True)
_sketch = value
_sketchThumbnail = GetThumbnail(_sketch)
PropertyHasChanged("Sketch")
PropertyHasChanged("SketchThumbnail")
End Set
End Property
Public ReadOnly Property SketchThumbnail() As Drawing.Bitmap
<System.Runtime.CompilerServices.MethodImpl(Runtime.CompilerServices.MethodImplOptions.NoInlining)> _
Get
CanReadProperty("SketchThumbnail", True)
Return _sketchThumbnail
End Get
End Property
Private Shared Function GetThumbnail(ByVal imageIn As Drawing.Bitmap) As Drawing.Bitmap
Dim myThumb As Drawing.Bitmap
If imageIn IsNot Nothing Then
myThumb = CType(imageIn.GetThumbnailImage(25, 25, Nothing, New System.IntPtr), Drawing.Bitmap)
Else
myThumb = Nothing
End If
Return myThumb
End Function
I have tried a variety of ways to get this to update but no dice. Any help would be greatly appreciated.
dufflepud replied on Wednesday, January 30, 2008
I should have mentioned this is a winform project and I am using CSLA 2.0
Thanks.
tmg4340 replied on Thursday, January 31, 2008
I am not a thumbnail expert, but based on the MSDN docs, I'm wondering if your "GetThumbnail" routine is working properly. According to the docs on "GetThumbnailImage", you must pass a callback delegate for your third parameter, and the fourth parameter must be "IntPtr.Zero" (which may be different than a new, uninitialized pointer value.)
I can't say whether that's affecting your overall issue, but it's something you might want to look into.
- Scott
dufflepud replied on Thursday, January 31, 2008
Thanks for the ideas Scott. The initial load of the thumbnail does work. It seems to be an issue of the thumbnail bitmap variable not changing - like it is cached or the memory that is being pointed to isn't pointed to a new area or something strange like that.
I made the following changes but it didn't have any affect:
Private Function GetThumbnail(ByVal imageIn As Drawing.Bitmap) As Drawing.Bitmap
Dim myThumb As Drawing.Bitmap
If imageIn IsNot Nothing Then
myThumb = CType(imageIn.GetThumbnailImage(25, 25, MyCallBack, IntPtr.Zero), Drawing.Bitmap)
Else
myThumb = Nothing
End If
Return myThumb
End Function
Private Function MyCallBack() As Drawing.Bitmap.GetThumbnailImageAbort
Return Nothing
End Function
I'm not sure what the delegate should do but I assume it is for something like a cancel button or something to trigger an abort of the process. It is being called though so that doesn't make a whole lot of sense. I added a line in there with PropertyHasChanged("SketchThumbnail") just to see if it would change the image in the grid after a bit but it doesn't. At this point I am very confused. I even changed the sketchthumbnail property to public and tried setting it from the UI but even there it doesn't update it.
Here is the UI side in case it might show what I am doing wrong:
Private Sub AHERAResultsEnhancedDGV1_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles AHERAResultsEnhancedDGV1.CellDoubleClick
Dim mAHERA As AHERAResult
If AHERAResultsEnhancedDGV1.Columns(e.ColumnIndex).Name = "Sketch" Then
Dim rowguid As Guid
rowguid = CType(AHERAResultsEnhancedDGV1.Rows(e.RowIndex).Cells("RowGUIDColumn").Value, Guid)
mAHERA = _analysis.AHERAResults.FindByID(rowguid)
Using sketchForm As frmSketch = frmSketch.GetInstance
sketchForm.Bitmap = mAHERA.SketchThumbnail
If sketchForm.ShowDialog() = Windows.Forms.DialogResult.OK Then
'show me the thumbnail going in
End If
End Using
Using sketchForm As frmSketch = frmSketch.GetInstance
sketchForm.Bitmap = mAHERA.Sketch
If sketchForm.Bitmap Is Nothing Then
sketchForm.Bitmap = sketchForm.MakeNewBitmap() 'call form to make sure size is correct.
End If
If sketchForm.ShowDialog() = Windows.Forms.DialogResult.OK Then
mAHERA.Sketch = sketchForm.Bitmap
End If
End Using
Using sketchForm As frmSketch = frmSketch.GetInstance
sketchForm.Bitmap = mAHERA.SketchThumbnail
If sketchForm.ShowDialog() = Windows.Forms.DialogResult.OK Then
'show me the thumbnail coming out
End If
End Using
End If
End Sub
Thanks again for any help.
Glenn
tmg4340 replied on Thursday, January 31, 2008
Well - the only other thing I can suggest is something I saw in either a forum post or one of Rocky's e-books. Basically, in a WinForms data-binding scenario, once you have bound your object, you should never directly interact with the object properties. Instead, you should interact with the BindingSource control. That may be your problem, as the BindingSource may not be propagating to the grid properly. I would leave the "GetThumbnailImage" changes too, though it appears they didn't make a difference.
HTH
- Scott
dufflepud replied on Thursday, January 31, 2008
Scott,
It definitely is something wacky with the GetThumbnailImage. When I just assign the non-thumnail to the property it updates fine. I am going to see what other options I have there.
Thanks for your help.
Glenn
dufflepud replied on Monday, February 04, 2008
I think I have something that will work. Just in case someone else might find this helpful here is the code that seems to take care of this for me.
Private Function GetThumbnail(ByVal imageIn As Drawing.Image) As Drawing.Image
Dim myThumb As Drawing.Image
If imageIn IsNot Nothing Then
Dim newsize As Drawing.Size = New Drawing.Size(25, 25)
myThumb = New Drawing.Bitmap(imageIn, newsize)
Else
myThumb = Nothing
End If
Return myThumb
End Function
I did change everything to drawing.image rather than drawing.bitmap but either should work.
Also getting and storing the image data as a byte string image field was confusing for me so in case it might help someone here is the code I used.
'get the bitmap
Dim bufferSize As Integer = 100
Dim mByteImage(bufferSize - 1) As Byte
Dim retVal As Long
Dim startIndex As Long = 0
Using stream As New System.IO.MemoryStream
startIndex = 0
retVal = .GetBytes("Sketch", startIndex, mByteImage, 0, bufferSize)
If retVal > 0 Then
Do While retVal = bufferSize
stream.Write(mByteImage, 0, mByteImage.Length)
stream.Flush()
startIndex += bufferSize
retVal = .GetBytes("Sketch", startIndex, mByteImage, 0, bufferSize)
Loop
stream.Write(mByteImage, 0, CInt(retVal))
Sketch = New Drawing.Bitmap(stream) 'use property to make sure thumb is assigned
Else
Sketch = Nothing
End If
End Using
'saving it here was the parameter
cm.Parameters.Add("@Sketch", SqlDbType.Image).Value = ConvertToByteArray(_sketch)
'and here is the function
Public Shared Function ConvertToByteArray(ByVal value As Drawing.Image) As Byte()
If value IsNot Nothing Then
Dim bitmapBytes As Byte()
Using stream As New System.IO.MemoryStream
value.Save(stream, value.RawFormat)
bitmapBytes = stream.ToArray
End Using
Return bitmapBytes
Else
Return Nothing
End If
End Function
Copyright (c) Marimer LLC