Question Picturebox's graphics

eltincho2202

Member
Joined
Jul 26, 2010
Messages
8
Programming Experience
1-3
Hi everyone,

I'm having troubles while building a bar chart with graphics.

What happens is that I create the bar chart correctly and it looks perfect, but when I click outside the picturebox or just change the window, the bar chart disappear completely, leaving the picturebox empty.

What can I do?

Thanks!
 
You're obviously doing something wrong, but it's hard for us to know what that might be without seeing what you're actually doing. If you have code that doesn't work, it's always a good idea to post that code. Only the relevant code, mind you. Not the entire application.

That said, the most likely issue is that you are doing your drawing in the wrong place. When drawing on controls, you must NEVER do any drawing anywhere other than on that control's Paint event, which means in its own OnPaint method or in a method that handles its Paint event. Windows forms uses GDI+, which erases and paints controls over and over at often unpredictable times. Any drawing you do on a control will be erased the next time that control gets painted, which is why you must do the drawing every time the control is painted, which is why you must do the drawing on the Paint event.

Having said all that, why use GDI+ at all? VS 2010 includes a very functional Chart control. If you want to learn how to use it:

Samples Environment for Microsoft Chart Controls - Home
 
.

Thanks for the answer :)

here is the code:

VB.NET:
Dim penBrown As Brush = Brushes.Brown
        Dim penBlue As Brush = Brushes.Blue
        Dim penRed As Brush = Brushes.Red
        Dim penPurple As Brush = Brushes.Purple
        Dim penGreen As Brush = Brushes.Green
        Dim penYellow As Brush = Brushes.Yellow
        Dim penOrange As Brush = Brushes.Orange
        Dim penLightBlue As Brush = Brushes.LightBlue
        Dim penSilver As Brush = Brushes.Silver
        Dim penGold As Brush = Brushes.Gold
        Dim penPink As Brush = Brushes.Pink
        Dim penGray As Brush = Brushes.Gray


        Dim mesesArrayGraduaciones(12) As Integer
        Dim colPens As New List(Of Brush)


        colPens.Add(penBrown)
        colPens.Add(penBlue)
        colPens.Add(penRed)
        colPens.Add(penPurple)
        colPens.Add(penGreen)
        colPens.Add(penYellow)
        colPens.Add(penOrange)
        colPens.Add(penLightBlue)
        colPens.Add(penSilver)
        colPens.Add(penGold)
        colPens.Add(penPink)
        colPens.Add(penGray)



        For x As Integer = 0 To 11

            Dim mes As Integer = x + 1

            For Each unaGraduacion As Graduacion In colGraduaciones
                If unaGraduacion.Mes = mes Then
                    mesesArrayGraduaciones(x) += unaGraduacion.CantidadAlumnos
                End If
            Next

        Next


        Dim graphic As Graphics = pbxEstadisticas.CreateGraphics()


        graphic.Clear(Color.White)

        Dim nextPos As Integer = 30

        Dim tamanoTotalIngresos As Integer = pbxEstadisticas.Height

        Dim maxSize As Integer = 0


        For Each unInteger As Integer In mesesArrayGraduaciones

            If (unInteger > maxSize) Then
                maxSize = unInteger
            End If

        Next

        If maxSize = 0 Then
            maxSize = 1
        Else
            maxSize += 10
        End If

        For x As Integer = 0 To 11

            Dim valor As Integer = mesesArrayGraduaciones(x)
            Dim posY As Integer = Common.getSize(maxSize, pbxEstadisticas.Height, valor)
            Dim valorFinal As Integer = pbxEstadisticas.Height - posY

            'Dim posStatsY As Integer = pbxEstadisticas.Location.Y + valorFinal - 10


            Dim posLabelY As Integer = (pbxEstadisticas.Height - 20) - CInt((valor * pbxEstadisticas.Height) / maxSize)

            'If (posLabelY < pbxEstadisticas.Location.Y) Then
            '    posLabelY = 0
            'End If

            Dim posLabelX As Integer = nextPos

            If CStr(valor).Length = 1 Then
                posLabelX += 6
            ElseIf CStr(valor).Length = 2 Then
                posLabelX += 2
            Else
                posLabelX -= 4
            End If

            graphic.FillRectangle(colPens(x), nextPos, posY, 30, valorFinal)
            graphic.DrawString(CStr(valor), New Font("Microsoft Sans Serif", 12, FontStyle.Bold), Brushes.Black, New Point(posLabelX, posLabelY))

            nextPos += 40

        Next

        graphic.Dispose()


Don't worry about the names of the variables, cause they are in spanish. I don't know how you name pictureboxes, but my picturebox is the one called pbxEstadisticas.

The function Common.getSize() returns a double that indicates the size of the bar.

It's important to know that the bar chart is a monthly bar chart, so there will always be 12 bars.

Thanks gang!
 
I can see that you're calling CreateGraphics there, which you should never do. Is that code in an OnPaint method or a Paint event handler? If not then that's exactly what the problem is, as I said in my previous post.
 
Use the Paint event of pbxEstadisticas control. Draw using e.Graphics. If you need to force the control to repaint call the Refresh method of that control.
 
How do I call this method? Cause I call the Refresh method but it does not work...

What I want to do is, when the user clicks on one button, the picturebox displays the bar chart.

Thanks for all!
 
ok, I've done this :) I just created a variable that I use as a flag, so when the variable is in true, the barchart is displayed, otherwise nothing happens.

Thanks for all!!!!
 
Another thing you can do, if the chart isn't to change dynamically, is to draw the stuff to a Bitmap and display that in the Picturebox control. To do this create a Bitmap instance and use the Graphics.FromImage method.
 
Thanks! I'll consider that, but I can't use it here cause I'm using data from a database, and it's updated constantly. Thanks for your help guys!
 
this code executes when a button is clicked.
This is what I meant actually. If it is something you need to generate only when a button is clicked then you don't need to generate it every time the form needs to repaint.
 
Back
Top