picture box refresh problem

techvoodoo

Member
Joined
Nov 20, 2006
Messages
10
Programming Experience
3-5
I have a form with 9 picture boxes on it. The images in the picture boxes are .png files with a transparent background. The transparency is working great by setting the picture box back color to transparent and making the transparent .png files.

The problem I am having is, when the screen is loaded, minimized, or refreshed in anyway, the images disappear and reappear. It looks really unprofessional.

Is there any way to prevent this? It's a bug that has been driving me crazy. Thank you.
 
I believe the fix you are looking for will be to DoubleBuffer the PictureBox controls, though I cannot say for certain. I'm trying to find some reference material to back that up but you might look for the same in the mean time.
 
I have read about setting doublebuffer, but I was unable to find it. It's not in the properties box for the control.

I have found that it only occurs when I have a Background image on the Form. If I remove the background image the issue doesn't occur.

This got me thinking, why not put my bg image in a large picture box behind the 9 I have on the form. Well that doesn't work either. The transparency of the images in the picture box gets screwed up.

I appreciate any help.
 
If this is a complex image on the background of the form then it is going to take time to paint it, based on it's size/resolution etc.. If you want to try doublebuffering you need to use the

SetStyle(ControlStyles.OptimzedDoubleBuffer,True)


However you will find that this is only any good to you if you are implementing custom painting as most of the toolbox controls implement doublebuffering somewhere down the line. You could create your own doublebuffer class using some bitmaps, but at the end if the day it's the background image of the form that is the problem here isn't it?
Incidently, do you just get this problem inside the IDE? Have you tried building a release version and try starting it from double clicking the .exe?
 
The background image on the form I'm trying to use here isn't that complex. It's 150kb, 800x600 .jpg image. I'm not sure why it's causing so much headache.

I'm not clear on how to use the setstyle call. Do I just want to set use it on my form in the load event, i.e.:

me.SetStyle(ControlStyles.OptimzedDoubleBuffer,True)

which seems to do nothing. I have a good deal of experience with old ASP and Vb6 but not much in .Net so I've been a bit confused about some things.

Perhaps what I'm trying to do isn't even the best way. Here is the graphic I'm working with.

http://img123.imageshack.us/img123/5570/tablegraphicsbn5.jpg

What I'm making is a poker game. I have designed these graphics in photoshop in layers. The background and poker table I export out and that is what I set as the bgimage of my Win Form, a 800x600 .jpg.

Each of the avatar/people images are saved individually as 128x112 pixel images .png files, with transaparent backgrounds. I have 9 pictureboxes on my form I load those into, set the background color of the picture box to transparent, and thats that.

The boxes with the player name and money amounts are just lables in VB, and the cards will just be more picture boxes (haven't gotten to that yet).

Everything looks good, except when the form is refreshed for any reason (minimized, another window goes over top of it, ect.) That is when the avatar picture boxes disappear and redraw.

So like I was saying, perhaps there is a better way to do what I want. I considered DirectX but it seemed that what I was doing was so simple with basicly no animation, that the method I was trying would work.

Thanks again for any help anyone can offer.
 
You say it's unprofessional yet I've seen the same symptoms in apps by Microsoft, Windows Live OneCare for example. The background is a gradient type image, fairly simple.
 
I'm ready to blow my brains out, LOL. Now i've setup the picturebox for the dealer button (for those not familiar with poker the white disk with the D on it). That rotates around the table each hand.

It's a 32x32 px .png file in a picturebox. It moves from position 1, infront of an avatar, to position 2 infront of the next avatar, and so on. No animation, just pops from 1 spot to the next to the next.

It is having the same issue each time it moves. There is a refreshing/redrawing flicker, where it just shows a grey box for a split second before it is moved to the next spot. It also flickers like the avatars do, creating a grey box for a second, when the screen is minimized, or another screen is over it then the poker table screen is brought to the foreground.

I'm starting to think VB just isn't capable of handeling this type of graphical manipulation. I don't see why that would be, this is some pretty simple picture boxes and form background, not 3d animation.

I've attached my code and image files, perhaps someone would be kind enough to check it out and maybe find some kind of fix? I'm just making this program for fun for friends of mine to play poker with but I'm somewhat critical of small details and I wouldn't really want to show it as a final product (from from final product) if it has basic graphical glitches like this.

Thanks a million for the help.
 

Attachments

  • PokerClient.zip
    479.3 KB · Views: 85
Now this is odd, I found this code on another site:

VB.NET:
[SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff]Me[/COLOR][/SIZE][SIZE=2].SetStyle(ControlStyles.OptimizedDoubleBuffer [/SIZE][SIZE=2][COLOR=#0000ff]Or[/COLOR][/SIZE][SIZE=2] ControlStyles.UserPaint [/SIZE][SIZE=2][COLOR=#0000ff]Or[/COLOR][/SIZE][SIZE=2] ControlStyles.AllPaintingInWmPaint, [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE][SIZE=2])
[/SIZE]

I put that in the Public Sub New after the InitializeCompenent() procedure call, and it fixed the graphics problem with the dealer button icon/graphic, however it did nothing for my other images (the 9 avatar/player graphics).

Any ideas?
 
VB.NET:
 [LEFT]Me.SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint, True)
[/LEFT]

Yes that line turns on the stylebits that enable doublebuffering, intercepts thew wm_erasebackground message, and tells the operating system that the object will handle it's own painting. None of which will solve your problem here.​
 
VB.NET:
 [LEFT]Me.SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint, True)[/LEFT]

Yes that line turns on the stylebits that enable doublebuffering, intercepts thew wm_erasebackground message, and tells the operating system that the object will handle it's own painting. None of which will solve your problem here.

That line did resolve the issue with moving the picture box which contains the deal button icon, however it did nothing for the graphics when the whole screen is minimized or covered by another window than brought back up to be the front/active window.

Any thoughts on how, if at all, it is possible to resolve this issue? I do have the problem both from within the IDE and when I build a release compile of the project.
 
Ok, after giving this some thought. I think i may be on to something. Try the following.

Set the BackgroundImageLayout property of the form to 'Stretch'

Override the BackgroundImageProperty and add a class level variable to the form as follows.

VB.NET:
Private BackgroundBitmap as Bitmap
 
Public Overrides Property BackgroundImage as .....
Get
Return Me.BackGroundBitmap
End Get
Set (Byval ........)
Dim Img as image = Value
Me.BackgroundBitmap = new Bitmap(Me.Width,Me.Height, System.Drawing.Imaging.PixelFormat32bppARGB)
Dim G as Graphics = Graphics.FromImage(Me.BackgroundBitmap)
g.DrawImage(Img,0,0,Me.Width,Me.Height)
End Set
End Property
In the forms Constructor..


VB.NET:
MyBase.SetStyle(ControlStyles.OptimizedDoubleBuffer,True)
MyBase.SetStyle(ControlStyles.AllPaintingInWmPaint,True)
MyBase.SetStyle(ControlStyles.UserPaint,True)

Finally..

Get rid of all of the pictureboxes and draw the images in the overriden OnPaint using Graphics.DrawImage.

I'll stick my neck on the line and say.. Problem Solved.:)
 
Ok, after giving this some thought. I think i may be on to something. Try the following.

Set the BackgroundImageLayout property of the form to 'Stretch'

Override the BackgroundImageProperty and add a class level variable to the form as follows.

VB.NET:
Private BackgroundBitmap as Bitmap
 
Public Overrides Property BackgroundImage as .....
Get
Return Me.BackGroundBitmap
End Get
Set (Byval ........)
Dim Img as image = Value
Me.BackgroundBitmap = new Bitmap(Me.Width,Me.Height, System.Drawing.Imaging.PixelFormat32bppARGB)
Dim G as Graphics = Graphics.FromImage(Me.BackgroundBitmap)
g.DrawImage(Img,0,0,Me.Width,Me.Height)
End Set
End Property
In the forms Constructor..


VB.NET:
MyBase.SetStyle(ControlStyles.OptimizedDoubleBuffer,True)
MyBase.SetStyle(ControlStyles.AllPaintingInWmPaint,True)
MyBase.SetStyle(ControlStyles.UserPaint,True)

Finally..

Get rid of all of the pictureboxes and draw the images in the overriden OnPaint using Graphics.DrawImage.

I'll stick my neck on the line and say.. Problem Solved.:)

what should i put in "Public Overrides Property BackgroundImage as ....."???

and Set (Byval ........)
Dim Img as image = Value
?

sorry im a newbie :) hope you can help me sir vis :(:eagerness::dunce:
 
Wow,orignal post is old. Trojan 2012 this is based on the example of the original post. You really should've started a new thread.

Wouldn't just invalidating the image boxes work so that only the regions that needed repainting got repainted?
Repainting everything and double buffering unless animated images are shown seems to be excessive to me.
You can do this in any area of your code or override paint methods if you wanted.
You are repainting everything which is not needed as VB will do that anyway on maximise or resize or when a form is uncovered from another app.
Another thing you can do for speed is use a bitmap as your background image. Every image on your screen is a bitmap. A block of pixels is a bitmap. The encoding of the file is a jpeg. VB converts a jpeg to a bitmap to display it.
Sent using Tapatalk 2

Updated:
VB.NET:
Private Sub PictureBox1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.Resize
        PictureBox1.Invalidate()
End Sub

Another way you could do what you wanted, and how i would do it is to set your background image into the tag property, so that you keep an original. Paint your background image using a graphics object (the canvas), then paint your cards onto it.

VB.NET:
Imports system.drawing

        Dim nBackground As Image = Image.FromFile(Application.StartupPath + "\images\Background.png") 
' you can load you picture on startup to picturebox1.tag = Image.FromFile(Application.StartupPath + "\images\Background.png")
' then in your draw routine load it from the tag so that you are not reading it from disk.
        Dim nCard1 As Image = Image.FromFile(Application.StartupPath + "\images\Card1.png")
        Dim nCard2 As Image = Image.FromFile(Application.StartupPath + "\images\Card2.png")
Blah..blah for the 9 cards
        .
        .
        Dim Background As New Bitmap(nBackground )
        Dim Card1 As New Bitmap(nCard1 )
        Dim Card2 As New Bitmap(nCard2)
Blah..blah for the 9 cards
        .
        .
        ' IMAGE RESULT STORED IN THIS IMAGE
        Dim NewImage As Bitmap

        ' CREATE A GRAPHIC BASE TO DRAW ON FROM THAT
        NewImage = New Bitmap(PictureBox1.Width, PictureBox1.Height)
       
        ' CREATE A GRAPHIC OBJECTFROM THE SECOND IMAGE
        Dim GR As Graphics = Graphics.FromImage(NewImage)

       GR.DrawImage(Card1, New Rectangle(posX, PosY, xSize, ySize)) ' each card will have different locations - this is just an example
       GR.DrawImage(Card2, New Rectangle(posX, PosY, xSize, ySize))
Blah..blah for the 9 cards, draw what you want top most - last (such as poker chips on the cards)

        PictureBox1.Image = NewImage
        PictureBox1.Refresh()

        ' DISPOSE OF THE GRAPHICS CONTROL
        GR.Dispose()

Now you only have one image because you have drawn them all to the graphics object, then put that as one image into the picturebox, there will be no transparency issues.
 
Last edited:
Back
Top