List (of Label) em .NET

zbenta

Power Member
Boas pessoal

Criei uma estrutura de dados do tipo List em que os elementos da lista são Labels que necessito de tornar visíveis ao utilizador.

Após ter povoado a List com várias labels corro o seguinte código:

Código:
Dim labelname As Integer


        If labellist.Count = positionlist.Count Then


            For labelname = 0 To positionlist.Count - 1

               
                labellist(labelname).AutoSize = True
                labellist(labelname).BackColor = Color.Red
                labellist(labelname).BindingContext = BindingContext
                labellist(labelname).ForeColor = Color.Black
                labellist(labelname).Location = New Point(451, 402) 
                labellist(labelname).Parent = Me
                labellist(labelname).Show()
                labellist(labelname).Text = "teste" & labelname
                labellist(labelname).Visible = True

            Next labelname

Após correr o programa não consigo ver nenhuma das labels que sei que existem e foram criadas, pois verifico na Immediate window que tal sucedeu.

Peço a vossa ajuda pois ando às aranhas com isto.
 
Código:
labellist(labelname).Location = New Point(451, 402)
ja reparaste que assim as labels ficam umas em cima das outras?

Eu faria assim, subsituindo o "location":

Código:
labellist(labelname).Left = 451
labellist(labelname).top = 402+(30*labelName)
nem sei se isto funca assim, mas deixo o bitaite.
 
Adicionei à "labellist" que é declarada no mesmo form em que este código é executado.
Mas atenção, o acrescento de labels à "labellist" (labellist.add(somelabel)) é feitopor um método que se encontra numa classe que é utilizada pelo form onde originalmente a lista é declarada.

Será que me fiz entender ???



Yap isso foi feito de propósito

Yap, isso de sobrepor as labels foi feito de propósito
 
Última edição pelo moderador:
pergunta estúpida: qual é a dimensão do form?
é que, aparentemente, está tudo correcto...

Eu costumo dizer que não há perguntas estúpidas apenas duvidas engraçadas ;)
"Size 930; 445"
Creio que o location das labels está dentro dos limites, se é isso que estas a pensar :x2:
 
Agora estou na dúvida?
O frmgrafico faz uso da classe gantchart e é na gantchart onde crio a label e chamo a função para inserir a label na labellist:


Código:
        Dim somelabel As New Label
        somelabel.Name = "label" & intnrlabels
        Call frmgrafico.adicionalabel(somelabel)

por usa vez no frmgrafico a funcção adicionalabel faz o seguinte:

Código:
   Public Sub adicionalabel(ByVal lbl As Label)
        labellist.Add(lbl)
    End Sub


O "Me" é o frmgrafico pois apesar de não ser local onde a label foi criada é o local onde existe a labellist e onde as labels deverão ser mostradas ao utilizador.
 
Última edição pelo moderador:
tens razão ;)
pah, não estou a ver a razão de não conseguires ver as labels :/

bitaite: tenta definir as dimensões das labels manualmente
 
Eu também já estou pelos cabelos, já tentei de tudo.
em relação às dimensões elas são autosize, por isso expandem e contraem conforme o tamanho do texto lá inserido.
Já ando nisto à 2 dias e não saio da cepa torta.
Obrigado na mesma pela ajuda .
 
Oki doki, vou tentar e digo qualquer coisa.

Reparei agora mesmo num pormenor interessante.
Quando o frmgrafico chama a classe gantchart para que esta mostre o gráfico, o conteúdo da labellist é apagado.
Porque será???
 
Última edição pelo moderador:
É um "bocadito" grande, mas aqui vai.

Código:
Imports System.Drawing.Drawing2D

''' <summary>
''' Adds a Gantt Chart to the form
''' This is for private use only. For use in non-private projects you'll need permission from me, 
''' which can be obtained by contacting me: [email protected]
''' 
''' Created by Adrian "Adagio" Grau
''' 
''' Version 0.54
''' </summary>
''' <remarks></remarks>

Public Class GanttChart
    Inherits Control

    Private bars As New List(Of ChartBarDate)
    Private headerFromDate As Date = Nothing
    Private headerToDate As Date = Nothing

    Private barStartRight As Integer = 20
    Private barStartLeft As Integer = 100
    Private headerTimeStartTop As Integer = 30
    Private shownHeaderList As List(Of Header)

    Private barStartTop As Integer = 50
    Private barHeight As Integer = 9
    Private barSpace As Integer = 5

    Private widthPerItem As Integer

    Private _mouseOverColumnValue As Date = Nothing
    Private _mouseOverRowText As String = ""
    Private _mouseOverRowValue As Object = Nothing

    Private lineColor As Pen = Pens.Bisque
    Private dateTextFont As Font = New Font("VERDANA", 8.0, FontStyle.Regular, GraphicsUnit.Point)
    Private timeTextFont As Font = New Font("VERDANA", 8.0, FontStyle.Regular, GraphicsUnit.Point)
    Private rowTextFont As Font = New Font("VERDANA", 8.0, FontStyle.Regular, GraphicsUnit.Point)

    Friend WithEvents ToolTip As New System.Windows.Forms.ToolTip()

    Public Event MouseDragged(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)

    ' added by zbenta
    Public intnrlabels As Integer
    ' end of added by zbenta

    Dim objBmp As Bitmap
    Dim objGraphics As Graphics

#Region "Public properties"

    ''' <summary>
    ''' The start date/time of the chart
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Property FromDate() As Date
        Get
            Return headerFromDate
        End Get
        Set(ByVal value As Date)
            headerFromDate = value
        End Set
    End Property

    ''' <summary>
    ''' The end date/time of the chart
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Property ToDate() As Date
        Get
            Return headerToDate
        End Get
        Set(ByVal value As Date)
            headerToDate = value
        End Set
    End Property

    ''' <summary>
    ''' The text for the current row the mouse hovers above
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public ReadOnly Property MouseOverRowText() As String
        Get
            Return _mouseOverRowText
        End Get
    End Property

    ''' <summary>
    ''' The value for the current bar the mouse hovers above
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public ReadOnly Property MouseOverRowValue() As Object
        Get
            Return _mouseOverRowValue
        End Get
    End Property

    ''' <summary>
    ''' The date/time the mouse hovers above
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public ReadOnly Property MouseOverColumnDate() As Date
        Get
            Return _mouseOverColumnValue
        End Get
    End Property

    ''' <summary>
    ''' The color of the grid
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Property GridColor() As System.Drawing.Pen
        Get
            Return lineColor
        End Get
        Set(ByVal value As System.Drawing.Pen)
            lineColor = value
        End Set
    End Property

    ''' <summary>
    ''' The font used for the row text
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Property RowFont() As Font
        Get
            Return rowTextFont
        End Get
        Set(ByVal value As Font)
            rowTextFont = value
        End Set
    End Property

    ''' <summary>
    ''' The font used for the "date" text in the columns
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Property DateFont() As Font
        Get
            Return dateTextFont
        End Get
        Set(ByVal value As Font)
            dateTextFont = value
        End Set
    End Property

    ''' <summary>
    ''' The font used for the "time" text in the colums)
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Property TimeFont() As Font
        Get
            Return timeTextFont
        End Get
        Set(ByVal value As Font)
            timeTextFont = value
        End Set
    End Property

#End Region

#Region "Constructor"

    ''' <summary>
    ''' Default constructor
    ''' </summary>
    ''' <remarks></remarks>

    Public Sub New()
        ToolTip.AutoPopDelay = 15000
        ToolTip.InitialDelay = 250
        ToolTip.OwnerDraw = True

        objBmp = New Bitmap(1280, 1024, Imaging.PixelFormat.Format24bppRgb)
        objGraphics = Graphics.FromImage(objBmp)

        ' Flicker free drawing

        Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint, True)
    End Sub

#End Region

#Region "Bars"

    Private Sub SetBarStartLeft(ByVal rowText As String)
        Dim gfx As Graphics = Me.CreateGraphics

        Dim length As Integer = gfx.MeasureString(rowText, rowTextFont, 500).Width

        If length > barStartLeft Then
            barStartLeft = length
        End If
    End Sub

    ''' <summary>
    ''' Adds a bar to the list
    ''' </summary>
    ''' <param name="rowText">Text for the row</param>
    ''' <param name="barValue">Value for the row</param>
    ''' <param name="fromTime">The date/time the bar starts</param>
    ''' <param name="toTime">The date/time the bar ends</param>
    ''' <param name="color">The color of the bar</param>
    ''' <param name="hoverColor">The hover color of the bar</param>
    ''' <param name="rowIndex">The rowindex of the bar (useful if you want several bars on the same row)</param>
    ''' <remarks></remarks>

    Public Sub AddChartBar(ByVal rowText As String, ByVal barValue As Object, ByVal fromTime As Date, ByVal toTime As Date, ByVal color As Color, ByVal hoverColor As Color, ByVal rowIndex As Integer)
        Dim bar As New ChartBarDate
        bar.Text = rowText
        bar.Value = barValue
        bar.StartValue = fromTime
        bar.EndValue = toTime
        bar.Color = color
        bar.HoverColor = hoverColor
        bar.RowIndex = rowIndex
        bars.Add(bar)

        'added by zbenta

        Dim somelabel As New Label
        somelabel.Name = "label" & intnrlabels
        Call frmgrafico.adicionalabel(somelabel)

        'end of added by zbenta

        SetBarStartLeft(rowText)
    End Sub

    ''' <summary>
    ''' Adds a bar to the list
    ''' </summary>
    ''' <param name="rowText">Text for the row</param>
    ''' <param name="barValue">Value for the row</param>
    ''' <param name="fromTime">The date/time the bar starts</param>
    ''' <param name="toTime">The date/time the bar ends</param>
    ''' <param name="color">The color of the bar</param>
    ''' <param name="hoverColor">The hover color of the bar</param>
    ''' <param name="rowIndex">The rowindex of the bar (useful if you want several bars on the same row)</param>
    ''' <param name="hideFromMouseMove">If you want to "hide" the bar from mousemove event</param>
    ''' <remarks></remarks>

    Public Sub AddChartBar(ByVal rowText As String, ByVal barValue As Object, ByVal fromTime As Date, ByVal toTime As Date, ByVal color As Color, ByVal hoverColor As Color, ByVal rowIndex As Integer, ByVal hideFromMouseMove As Boolean)
        Dim bar As New ChartBarDate
        bar.Text = rowText
        bar.Value = barValue
        bar.StartValue = fromTime
        bar.EndValue = toTime
        bar.Color = color
        bar.HoverColor = hoverColor
        bar.RowIndex = rowIndex
        bar.HideFromMouseMove = hideFromMouseMove
        bars.Add(bar)

        SetBarStartLeft(rowText)
    End Sub

    ''' <summary>
    ''' Gets the next index
    ''' </summary>
    ''' <param name="rowText"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Function GetIndexChartBar(ByVal rowText As String) As Integer
        Dim index As Integer = -1

        For Each bar As ChartBarDate In bars
            If bar.Text.Equals(rowText) = True Then
                Return bar.RowIndex
            End If
            If bar.RowIndex > index Then
                index = bar.RowIndex
            End If
        Next

        Return index + 1
    End Function

    ''' <summary>
    ''' Removes all bars from list
    ''' </summary>
    ''' <remarks></remarks>

    Public Sub RemoveBars()
        bars = New List(Of ChartBarDate)

        barStartLeft = 100
    End Sub

#End Region

#Region "Draw"

    ''' <summary>
    ''' Redraws the Gantt chart
    ''' </summary>
    ''' <remarks></remarks>

    Public Sub PaintChart()
        Me.Invalidate()
    End Sub

    ''' <summary>
    ''' Redraws the Gantt chart
    ''' </summary>
    ''' <param name="gfx"></param>
    ''' <remarks></remarks>

    Private Sub PaintChart(ByVal gfx As Graphics)

        gfx.Clear(Me.BackColor)

        If headerFromDate = Nothing Or headerToDate = Nothing Then Exit Sub

        DrawScrollBar(gfx)
        DrawHeader(gfx, Nothing)
        DrawNetHorizontal(gfx)
        DrawNetVertical(gfx)
        DrawBars(gfx)

        objBmp = New Bitmap(Me.Width - barStartRight, lastLineStop, Imaging.PixelFormat.Format24bppRgb)
        objGraphics = Graphics.FromImage(objBmp)


    End Sub

    ''' <summary>
    ''' Redraws the Gantt chart
    ''' </summary>
    ''' <param name="pe"></param>
    ''' <remarks></remarks>

    Protected Overrides Sub OnPaint(ByVal pe As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(pe)

        PaintChart(pe.Graphics)
    End Sub

    ''' <summary>
    ''' Draws the list of headers. Automatically shows which headers to draw, based on the width of the Gantt Chart
    ''' </summary>
    ''' <param name="gfx"></param>
    ''' <param name="headerList"></param>
    ''' <remarks></remarks>

    Private Sub DrawHeader(ByVal gfx As Graphics, ByVal headerList As List(Of Header))
        If headerList Is Nothing Then
            headerList = GetFullHeaderList()
        End If

        If headerList.Count = 0 Then Exit Sub

        Dim availableWidth = Me.Width - 10 - barStartLeft - barStartRight
        widthPerItem = availableWidth / headerList.Count

        If widthPerItem < 40 Then
            Dim newHeaderList As New List(Of Header)

            Dim showNext As Boolean = True

            ' If there's not enough room for all headers remove 50%

            For Each header As Header In headerList
                If showNext = True Then
                    newHeaderList.Add(header)
                    showNext = False
                Else
                    showNext = True
                End If
            Next

            DrawHeader(gfx, newHeaderList)
            Exit Sub
        End If

        Dim index As Integer = 0
        Dim headerStartPosition As Integer = -1
        Dim lastHeader As Header = Nothing

        For Each header As Header In headerList
            Dim startPos As Integer = barStartLeft + (index * widthPerItem)
            Dim showDateHeader As Boolean = False

            header.StartLocation = startPos

            ' Checks whether to show the date or not

            If lastHeader Is Nothing Then
                showDateHeader = True
            ElseIf header.Time.Hour < lastHeader.Time.Hour Then
                showDateHeader = True
            ElseIf header.Time.Minute = lastHeader.Time.Minute Then
                showDateHeader = True
            End If

            ' Show date

            If showDateHeader = True Then
                gfx.DrawString(header.Time.ToString("%d-%M"), dateTextFont, Brushes.Black, startPos, 0)
            End If

            ' Show time

            gfx.DrawString(header.HeaderText, timeTextFont, Brushes.Black, startPos, headerTimeStartTop)
            index += 1

            lastHeader = header
        Next

        shownHeaderList = headerList
        widthPerItem = (Me.Width - 10 - barStartLeft - barStartRight) / shownHeaderList.Count
    End Sub

    ''' <summary>
    ''' Draws the bars
    ''' </summary>
    ''' <param name="grfx"></param>
    ''' <remarks></remarks>

    Public Sub DrawBars(ByVal grfx As Graphics, Optional ByVal ignoreScrollAndMousePosition As Boolean = False)
        If shownHeaderList Is Nothing Then Exit Sub
        If shownHeaderList.Count = 0 Then Exit Sub

        Dim index As Integer = 0

        ' Finds pixels per minute

        Dim timeBetween As TimeSpan = shownHeaderList(1).Time - shownHeaderList(0).Time
        Dim minutesBetween As Integer = (timeBetween.Days * 1440) + (timeBetween.Hours * 60) + timeBetween.Minutes
        Dim widthBetween = (shownHeaderList(1).StartLocation - shownHeaderList(0).StartLocation)
        Dim perMinute As Decimal = widthBetween / minutesBetween

        ' Draws each bar

        For Each bar As ChartBarDate In bars
            index = bar.RowIndex

            Dim startLocation As Integer
            Dim width As Integer
            Dim startMinutes As Integer ' Number of minutes from start of the gantt chart
            Dim startTimeSpan As TimeSpan
            Dim lengthMinutes As Integer ' Number of minutes from bar start to bar end
            Dim lengthTimeSpan As TimeSpan

            Dim scrollPos As Integer = 0

            If ignoreScrollAndMousePosition = False Then
                scrollPos = scrollPosition
            End If

            ' Calculates where the bar should be located



            'added by zbenta : code alteration in order to enable the activities to be shown within the selected interval

            If bar.StartValue < FromDate Then
                bar.StartValue = FromDate
            End If

            If bar.EndValue > ToDate Then
                bar.EndValue = ToDate
            End If

            'end off added by zbenta

            startTimeSpan = bar.StartValue - FromDate
            startMinutes = (startTimeSpan.Days * 1440) + (startTimeSpan.Hours * 60) + startTimeSpan.Minutes

            startLocation = perMinute * startMinutes

            Dim endValue As Date = bar.EndValue

            If endValue = Nothing Then
                endValue = Date.Now
            End If

            lengthTimeSpan = endValue - bar.StartValue
            lengthMinutes = (lengthTimeSpan.Days * 1440) + (lengthTimeSpan.Hours * 60) + lengthTimeSpan.Minutes

            width = perMinute * lengthMinutes

            Dim a As Integer = barStartLeft + startLocation
            Dim b As Integer = barStartTop + (barHeight * (index - scrollPos)) + (barSpace * (index - scrollPos)) + 2
            Dim c As Integer = width
            Dim d As Integer = barHeight

            If c = 0 Then c = 1

            ' Stops a bar from going into the row-text area

            If a - barStartLeft < 0 Then
                a = barStartLeft
            End If

            Dim color As System.Drawing.Color

            ' If mouse is over bar, set the color to be hovercolor

            If MouseOverRowText = bar.Text And bar.StartValue <= _mouseOverColumnValue And bar.EndValue >= _mouseOverColumnValue Then
                color = bar.HoverColor
            Else
                color = bar.Color
            End If

            ' Set the location for the graphics

            bar.TopLocation.Left = New Point(a, b)
            bar.TopLocation.Right = New Point(a + c, b)
            bar.BottomLocation.Left = New Point(a, b + d)
            bar.BottomLocation.Right = New Point(a, b + d)

            Dim obBrush As LinearGradientBrush
            Dim obRect As New Rectangle(a, b, c, d)

            'added by zbenta set the center position of the bar

            Dim intcontador As Integer
            intcontador = frmgrafico.nrlinhas()
            If intnrlabels < intcontador Then

                Dim apoint As New Point
                apoint.X = (a + (a + c)) / 2
                apoint.Y = ((b + d) + b) / 2
                Call frmgrafico.preenche(apoint)
                intnrlabels = intnrlabels + 1
            End If

            'end of added by zbenta

            If bar.StartValue <> Nothing And endValue <> Nothing Then
                If (index >= scrollPos And index < barsViewable + scrollPos) Or ignoreScrollAndMousePosition = True Then

                    ' Makes the bar gradient

                    obBrush = New LinearGradientBrush(obRect, color, color.Gray, LinearGradientMode.Vertical)

                    ' Draws the bar

                    grfx.DrawRectangle(Pens.Black, obRect)
                    grfx.FillRectangle(obBrush, obRect)

                    ' Draws the rowtext

                    grfx.DrawString(bar.Text, rowTextFont, Brushes.Black, 0, barStartTop + (barHeight * (index - scrollPos)) + (barSpace * (index - scrollPos)))

                    obBrush = Nothing
                    obRect = Nothing
                    obBrush = Nothing
                End If
            End If
        Next
    End Sub

    ''' <summary>
    ''' Draws the vertical lines
    ''' </summary>
    ''' <param name="grfx"></param>
    ''' <remarks></remarks>

    Public Sub DrawNetVertical(ByVal grfx As Graphics)
        If shownHeaderList Is Nothing Then Exit Sub
        If shownHeaderList.Count = 0 Then Exit Sub

        Dim index As Integer = 0
        Dim availableWidth As Integer = Me.Width - 10 - barStartLeft - barStartRight
        Dim lastHeader As Header = Nothing

        For Each header As Header In shownHeaderList
            Dim headerLocationY As Integer = 0

            If lastHeader Is Nothing Then
                headerLocationY = 0
            ElseIf header.Time.Hour < lastHeader.Time.Hour Then
                headerLocationY = 0
            Else
                headerLocationY = headerTimeStartTop
            End If

            grfx.DrawLine(Pens.Bisque, barStartLeft + (index * widthPerItem), headerLocationY, barStartLeft + (index * widthPerItem), lastLineStop)
            index += 1

            lastHeader = header
        Next

        grfx.DrawLine(lineColor, barStartLeft + (index * widthPerItem), headerTimeStartTop, barStartLeft + (index * widthPerItem), lastLineStop)
    End Sub

    ''' <summary>
    ''' Draws the horizontal lines
    ''' </summary>
    ''' <param name="grfx"></param>
    ''' <remarks></remarks>

    Public Sub DrawNetHorizontal(ByVal grfx As Graphics)
        If shownHeaderList Is Nothing Then Exit Sub
        If shownHeaderList.Count = 0 Then Exit Sub

        Dim index As Integer = 0
        Dim width As Integer = (widthPerItem * shownHeaderList.Count) + barStartLeft

        For index = 0 To GetIndexChartBar("QQQQQQ") ' Last used index. Hopefully nobody will make a row named QQQ :o)
            For Each bar As ChartBarDate In bars
                grfx.DrawLine(lineColor, 0, barStartTop + (barHeight * index) + (barSpace * index), width, barStartTop + (barHeight * index) + (barSpace * index))
            Next
        Next

        lastLineStop = barStartTop + (barHeight * (index - 1)) + (barSpace * (index - 1))
    End Sub

    ' This is the position (in pixels, from top) of the last line. Used for drawing lines

    Private lastLineStop As Integer = 0

#End Region

#Region "Header list"

    ''' <summary>
    ''' Gets the full header list, consisting of hours between the two dates set
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Private Function GetFullHeaderList() As List(Of Header)
        Dim result As New List(Of Header)
        Dim newFromTime As New Date(FromDate.Year, FromDate.Month, FromDate.Day)
        Dim item As String

        Dim interval As TimeSpan = ToDate - FromDate

        If interval.Days > 1 Then
            While newFromTime <= ToDate
                Dim header As New Header

                header.HeaderText = ""
                header.Time = New Date(newFromTime.Year, newFromTime.Month, newFromTime.Day, 0, 0, 0)
                result.Add(header)

                newFromTime = newFromTime.AddDays(1) ' The minimum interval of time between the headers
            End While
        Else
            With newFromTime
                newFromTime = .AddHours(FromDate.Hour)

                If headerFromDate.Minute < 59 And headerFromDate.Minute > 29 Then
                    newFromTime = .AddMinutes(30)
                Else
                    newFromTime = .AddMinutes(0)
                End If
            End With

            While newFromTime <= ToDate
                item = newFromTime.Hour & ":"

                If newFromTime.Minute < 10 Then
                    item += "0" & newFromTime.Minute
                Else
                    item += "" & newFromTime.Minute
                End If

                Dim header As New Header

                header.HeaderText = item
                header.Time = New Date(newFromTime.Year, newFromTime.Month, newFromTime.Day, newFromTime.Hour, newFromTime.Minute, 0)
                result.Add(header)

                newFromTime = newFromTime.AddMinutes(5) ' The minimum interval of time between the headers
            End While
        End If

        Return result
    End Function

#End Region

#Region "Mouse Move"

    ''' <summary>
    ''' Finds the current row and column based on mouse position
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>

    Private Sub GanttChart_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
        If shownHeaderList Is Nothing Then Exit Sub
        If shownHeaderList.Count = 0 Then Exit Sub

        Dim LocalMousePosition As Point

        LocalMousePosition = Me.PointToClient(Cursor.Position)

        ' Finds pixels per minute

        Dim timeBetween As TimeSpan = shownHeaderList(1).Time - shownHeaderList(0).Time
        Dim minutesBetween As Integer = (timeBetween.Days * 1440) + (timeBetween.Hours * 60) + timeBetween.Minutes
        Dim widthBetween = (shownHeaderList(1).StartLocation - shownHeaderList(0).StartLocation)
        Dim perMinute As Decimal = widthBetween / minutesBetween

        ' Finds the time at mousepointer

        Dim minutesAtCursor As Integer = 0

        If LocalMousePosition.X > barStartLeft Then
            minutesAtCursor = (LocalMousePosition.X - barStartLeft) / perMinute
            _mouseOverColumnValue = FromDate.AddMinutes(minutesAtCursor)
        Else
            _mouseOverColumnValue = Nothing
        End If

        ' Finds the row at mousepointer

        Dim rowText As String = ""
        Dim rowValue As Object = Nothing
        Dim columnText As String = ""

        ' Tests to see if the mouse pointer is hovering above the scrollbar

        Dim scrollBarStatusChanged As Boolean = False

        ' Tests to see if the mouse is hovering over the scroll-area bottom-arrow

        If LocalMousePosition.X > BottomPart.Left And LocalMousePosition.Y < BottomPart.Right And LocalMousePosition.Y < BottomPart.Bottom And LocalMousePosition.Y > BottomPart.Top Then
            If mouseOverBottomPart = False Then
                scrollBarStatusChanged = True
            End If

            mouseOverBottomPart = True
        Else
            If mouseOverBottomPart = False Then
                scrollBarStatusChanged = True
            End If

            mouseOverBottomPart = False
        End If

        ' Tests to see if the mouse is hovering over the scroll-area top-arrow

        If LocalMousePosition.X > topPart.Left And LocalMousePosition.Y < topPart.Right And LocalMousePosition.Y < topPart.Bottom And LocalMousePosition.Y > topPart.Top Then
            If mouseOverTopPart = False Then
                scrollBarStatusChanged = True
            End If

            mouseOverTopPart = True
        Else
            If mouseOverTopPart = False Then
                scrollBarStatusChanged = True
            End If

            mouseOverTopPart = False
        End If

        ' Tests to see if the mouse is hovering over the scroll

        If LocalMousePosition.X > scroll.Left And LocalMousePosition.Y < scroll.Right And LocalMousePosition.Y < scroll.Bottom And LocalMousePosition.Y > scroll.Top Then
            If mouseOverScrollBar = False Then
                scrollBarStatusChanged = True
            End If

            mouseOverScrollBar = True
            mouseOverScrollBarArea = True
        Else
            If mouseOverScrollBar = False Then
                scrollBarStatusChanged = True
            End If

            mouseOverScrollBar = False
            mouseOverScrollBarArea = False
        End If

        ' If the mouse is not above the scroll, test if it's over the scroll area (no need to test if it's not above the scroll)

        If mouseOverScrollBarArea = False Then
            If LocalMousePosition.X > scrollBarArea.Left And LocalMousePosition.Y < scrollBarArea.Right And LocalMousePosition.Y < scrollBarArea.Bottom And LocalMousePosition.Y > scrollBarArea.Top Then
                mouseOverScrollBarArea = True
            End If
        End If

        ' Tests to see if the mouse pointer is hovering above a bar

        For Each bar As ChartBarDate In bars

            ' If the bar is set to be hidden from mouse move, the current bar will be ignored

            If bar.HideFromMouseMove = False Then
                If bar.EndValue = Nothing Then
                    bar.EndValue = Date.Now
                End If

                ' Mouse pointer needs to be inside the X and Y positions of the bar

                If LocalMousePosition.X > bar.TopLocation.Left.X And LocalMousePosition.X < bar.TopLocation.Right.X Then
                    If LocalMousePosition.Y > bar.TopLocation.Left.Y And LocalMousePosition.Y < bar.BottomLocation.Left.Y Then

                        ' If the current bar is the one where the mouse is above, the rowText and rowValue needs to be set correctly
                        ' Then exit for loop, as there is no reason to continiue testing

                        rowText = bar.Text
                        rowValue = bar.Value
                    End If
                End If
            End If
        Next

        ' A simple test to see if the mousemovement has caused any changes to how it should be displayed 
        ' It only redraws if mouse moves from a bar to blank area or from blank area to a bar
        ' This increases performance compared to having a redraw every time a mouse moves

        If (_mouseOverRowValue Is Nothing And Not rowValue Is Nothing) Or (Not _mouseOverRowValue Is Nothing And rowValue Is Nothing) Or scrollBarStatusChanged = True Then
            PaintChart()
        End If

        ' Sets the mouseover row value and text

        _mouseOverRowText = rowText
        _mouseOverRowValue = rowValue

        If e.Button = Windows.Forms.MouseButtons.Left Then
            RaiseEvent MouseDragged(sender, e)
        End If
    End Sub

    Private Sub GanttChart_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.MouseLeave
        _mouseOverRowText = Nothing
        _mouseOverRowValue = Nothing

        PaintChart()
    End Sub

#End Region

#Region "ToolTipText"

    Private _toolTipText As New List(Of String)
    Private _toolTipTextTitle As String = ""

    Private MyPoint As New Point(0, 0)

    ''' <summary>
    ''' The title to draw
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Property ToolTipTextTitle() As String
        Get
            Return _toolTipTextTitle
        End Get
        Set(ByVal value As String)
            _toolTipTextTitle = value
        End Set
    End Property

    ''' <summary>
    ''' Gets or sets the ToolTipText lines. Don't use the add function directly on this, use ToolTipText = value
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Public Property ToolTipText() As List(Of String)
        Get
            If _toolTipText Is Nothing Then _toolTipText = New List(Of String)
            Return _toolTipText
        End Get
        Set(ByVal value As List(Of String))
            _toolTipText = value

            Dim LocalMousePosition As Point

            LocalMousePosition = Me.PointToClient(Cursor.Position)


            If LocalMousePosition = MyPoint Then Exit Property

            MyPoint = LocalMousePosition

            ToolTip.SetToolTip(Me, ".")
        End Set
    End Property

    ''' <summary>
    ''' Draws the ToolTip window
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>

    Private Sub ToolTipText_Draw(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawToolTipEventArgs) Handles ToolTip.Draw
        If ToolTipText Is Nothing Then
            ToolTipText = New List(Of String)
            Exit Sub
        End If

        If ToolTipText.Count = 0 Then
            Exit Sub
        ElseIf ToolTipText(0).Length = 0 Then
            Exit Sub
        End If

        Dim x As Integer
        Dim y As Integer

        e.Graphics.FillRectangle(Brushes.AntiqueWhite, e.Bounds)
        e.DrawBorder()

        Dim titleHeight As Integer = 14
        Dim fontHeight As Integer = 12

        ' Draws the line just below the title

        e.Graphics.DrawLine(Pens.Black, 0, titleHeight, e.Bounds.Width, titleHeight)

        Dim lines As Integer = 1
        Dim text As String = ToolTipTextTitle

        ' Draws the title

        Using font As New Font(e.Font, FontStyle.Bold)
            x = (e.Bounds.Width - e.Graphics.MeasureString(text, font).Width) \ 2
            y = (titleHeight - e.Graphics.MeasureString(text, font).Height) \ 2
            e.Graphics.DrawString(text, font, Brushes.Black, x, y)
        End Using

        ' Draws the lines

        For Each str As String In ToolTipText
            Dim font As New Font(e.Font, FontStyle.Regular)

            If str.Contains("[b]") Then
                font = New Font(font.FontFamily, font.Size, FontStyle.Bold, font.Unit)
                str = str.Replace("[b]", "")
            End If

            Using font
                x = 5
                y = (titleHeight - fontHeight - e.Graphics.MeasureString(str, font).Height) \ 2 + 10 + (lines * 14)
                e.Graphics.DrawString(str, font, Brushes.Black, x, y)
            End Using

            lines += 1
        Next
    End Sub

    ''' <summary>
    ''' Automatically resizes the ToolTip window
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>

    Private Sub ToolTipText_Popup(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PopupEventArgs) Handles ToolTip.Popup
        If ToolTipText Is Nothing Then
            ToolTipText = New List(Of String)
        End If

        If ToolTipText.Count = 0 Then
            e.ToolTipSize = New Size(0, 0)
            Exit Sub
        ElseIf ToolTipText(0).Length = 0 Then
            e.ToolTipSize = New Size(0, 0)
            Exit Sub
        End If

        ' resizes the ToolTip window

        Dim height As Integer = 18 + (ToolTipText.Count * 15)
        e.ToolTipSize = New Size(200, height)
    End Sub

#End Region

#Region "ChartBar"

    Private Class ChartBarDate

        Friend Class Location

            Private _right As New Point(0, 0)
            Private _left As New Point(0, 0)

            Public Property Right() As Point
                Get
                    Return _right
                End Get
                Set(ByVal value As Point)
                    _right = value
                End Set
            End Property

            Public Property Left() As Point
                Get
                    Return _left
                End Get
                Set(ByVal value As Point)
                    _left = value
                End Set
            End Property

        End Class

        Private _startValue As Date
        Private _endValue As Date

        Private _color As Color
        Private _hoverColor As Color

        Private _text As String
        Private _value As Object

        Private _rowIndex As Integer

        Private _topLocation As New Location
        Private _bottomLocation As New Location

        Private _hideFromMouseMove As Boolean = False


        Public Property StartValue() As Date
            Get
                Return _startValue
            End Get
            Set(ByVal value As Date)
                _startValue = value
            End Set
        End Property

        Public Property EndValue() As Date
            Get
                Return _endValue
            End Get
            Set(ByVal value As Date)
                _endValue = value
            End Set
        End Property

        Public Property Color() As Color
            Get
                Return _color
            End Get
            Set(ByVal value As Color)
                _color = value
            End Set
        End Property

        Public Property HoverColor() As Color
            Get
                Return _hoverColor
            End Get
            Set(ByVal value As Color)
                _hoverColor = value
            End Set
        End Property

        Public Property Text() As String
            Get
                Return _text
            End Get
            Set(ByVal value As String)
                _text = value
            End Set
        End Property

        Public Property Value() As Object
            Get
                Return _value
            End Get
            Set(ByVal value As Object)
                _value = value
            End Set
        End Property

        Public Property RowIndex() As Integer
            Get
                Return _rowIndex
            End Get
            Set(ByVal value As Integer)
                _rowIndex = value
            End Set
        End Property

        Public Property HideFromMouseMove() As Boolean
            Get
                Return _hideFromMouseMove
            End Get
            Set(ByVal value As Boolean)
                _hideFromMouseMove = value
            End Set
        End Property

        Friend Property TopLocation() As Location
            Get
                Return _topLocation
            End Get
            Set(ByVal value As Location)
                _topLocation = value
            End Set
        End Property

        Friend Property BottomLocation() As Location
            Get
                Return _bottomLocation
            End Get
            Set(ByVal value As Location)
                _bottomLocation = value
            End Set
        End Property

    End Class

#End Region

#Region "Headers"

    Private Class Header

        Private _headerText As String
        Private _startLocation As Integer
        Private _time As Date

        Public Property HeaderText() As String
            Get
                Return _headerText
            End Get
            Set(ByVal value As String)
                _headerText = value
            End Set
        End Property

        Public Property StartLocation() As Integer
            Get
                Return _startLocation
            End Get
            Set(ByVal value As Integer)
                _startLocation = value
            End Set
        End Property

        Public Property Time() As Date
            Get
                Return _time
            End Get
            Set(ByVal value As Date)
                _time = value
            End Set
        End Property

    End Class

#End Region

#Region "Resize"

    ''' <summary>
    ''' On resize the Gantt Chart is redrawn
    ''' </summary>
    ''' <param name="e"></param>
    ''' <remarks></remarks>

    Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
        MyBase.OnResize(e)

        scrollPosition = 0

        ' Used for when the Gantt Chart is saved as an image

        If lastLineStop > 0 Then
            objBmp = New Bitmap(Me.Width - barStartRight, lastLineStop, Imaging.PixelFormat.Format24bppRgb)
            objGraphics = Graphics.FromImage(objBmp)
        End If

        PaintChart()
    End Sub

#End Region

#Region "Scrollbar"

    Private barsViewable As Integer = -1
    Private scrollPosition As Integer = 0
    Private topPart As Rectangle = Nothing
    Private BottomPart As Rectangle = Nothing
    Private scroll As Rectangle = Nothing
    Private scrollBarArea As Rectangle = Nothing

    Private mouseOverTopPart As Boolean = False
    Private mouseOverBottomPart As Boolean = False
    Private mouseOverScrollBar As Boolean = False
    Private mouseOverScrollBarArea As Boolean = False

    ''' <summary>
    ''' Draws a scrollbar to the component, if there's a need for it
    ''' </summary>
    ''' <param name="grfx"></param>
    ''' <remarks></remarks>

    Private Sub DrawScrollBar(ByVal grfx As Graphics)
        barsViewable = (Me.Height - barStartTop) / (barHeight + barSpace)
        Dim barCount As Integer = GetIndexChartBar("QQQWWW")
        If barCount = 0 Then Exit Sub

        Dim maxHeight As Integer = Me.Height - 30
        Dim scrollHeight As Decimal = (maxHeight / barCount) * barsViewable

        ' If the scroll area is filled there's no need to show the scrollbar

        If scrollHeight >= maxHeight Then Exit Sub

        Dim scrollSpeed As Decimal = (maxHeight - scrollHeight) / (barCount - barsViewable)

        scrollBarArea = New Rectangle(Me.Width - 20, 19, 12, maxHeight)
        scroll = New Rectangle(Me.Width - 20, 19 + (scrollPosition * scrollSpeed), 12, scrollHeight)

        topPart = New Rectangle(Me.Width - 20, 10, 12, 8)
        BottomPart = New Rectangle(Me.Width - 20, Me.Height - 10, 12, 8)

        Dim colorTopPart As Brush
        Dim colorBottomPart As Brush
        Dim colorScroll As Brush

        If mouseOverTopPart = True Then
            colorTopPart = Brushes.Black
        Else
            colorTopPart = Brushes.Gray
        End If

        If mouseOverBottomPart = True Then
            colorBottomPart = Brushes.Black
        Else
            colorBottomPart = Brushes.Gray
        End If

        If mouseOverScrollBar = True Then
            colorScroll = New LinearGradientBrush(scroll, Color.Bisque, Color.Gray, LinearGradientMode.Horizontal)
        Else
            colorScroll = New LinearGradientBrush(scroll, Color.White, Color.Gray, LinearGradientMode.Horizontal)
        End If

        ' Draws the top and bottom part of the scrollbar

        grfx.DrawRectangle(Pens.Black, topPart)
        grfx.FillRectangle(Brushes.LightGray, topPart)

        grfx.DrawRectangle(Pens.Black, BottomPart)
        grfx.FillRectangle(Brushes.LightGray, BottomPart)

        ' Draws arrows

        Dim points(2) As PointF
        points(0) = New PointF(topPart.Left, topPart.Bottom - 1)
        points(1) = New PointF(topPart.Right, topPart.Bottom - 1)
        points(2) = New PointF((topPart.Left + topPart.Right) / 2, topPart.Top + 1)

        grfx.FillPolygon(colorTopPart, points)

        points(0) = New PointF(BottomPart.Left, BottomPart.Top + 1)
        points(1) = New PointF(BottomPart.Right, BottomPart.Top + 1)
        points(2) = New PointF((BottomPart.Left + BottomPart.Right) / 2, BottomPart.Bottom - 1)

        grfx.FillPolygon(colorBottomPart, points)

        ' Draws the scroll area

        grfx.DrawRectangle(Pens.Black, scrollBarArea)
        grfx.FillRectangle(Brushes.DarkGray, scrollBarArea)

        ' Draws the actual scrollbar

        grfx.DrawRectangle(Pens.Black, scroll)
        grfx.FillRectangle(colorScroll, scroll)
    End Sub

    ''' <summary>
    ''' The Y-position of the center of the scroll
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>

    Private Property ScrollPositionY() As Integer
        Get
            If scroll = Nothing Then Return -1
            Return ((scroll.Height / 2) + scroll.Location.Y) + 19
        End Get
        Set(ByVal value As Integer)
            Dim barCount As Integer = GetIndexChartBar("QQQWWW")
            Dim maxHeight As Integer = Me.Height - 30
            Dim scrollHeight As Decimal = (maxHeight / barCount) * barsViewable
            Dim scrollSpeed As Decimal = (maxHeight - scrollHeight) / (barCount - barsViewable)
            Dim index As Integer = 0
            Dim distanceFromLastPosition = 9999

            ' Tests to see what scrollposition is the closest to the set position

            While index < barCount
                Dim newPositionTemp As Integer = (index * scrollSpeed) + (scrollHeight / 2) + (30 / 2)
                Dim distanceFromCurrentPosition = newPositionTemp - value

                If distanceFromLastPosition < 0 Then
                    If distanceFromCurrentPosition < distanceFromLastPosition Then
                        scrollPosition = index - 1
                        PaintChart()
                        Exit Property
                    End If
                Else
                    If distanceFromCurrentPosition > distanceFromLastPosition Then
                        scrollPosition = index - 1

                        ' A precaution to make sure the scroll bar doesn't go too far down

                        If scrollPosition + barsViewable > GetIndexChartBar("QQQWWW") Then
                            scrollPosition = GetIndexChartBar("QQQWWW") - barsViewable
                        End If

                        PaintChart()
                        Exit Property
                    End If
                End If

                distanceFromLastPosition = distanceFromCurrentPosition

                index += 1
            End While
        End Set
    End Property

    ''' <summary>
    ''' Scrolls one row up
    ''' </summary>
    ''' <remarks></remarks>

    Public Sub ScrollOneup()
        If scrollPosition = 0 Then Exit Sub

        scrollPosition -= 1

        PaintChart()
    End Sub

    ''' <summary>
    ''' Scrolls one row down
    ''' </summary>
    ''' <remarks></remarks>

    Public Sub ScrollOneDown()
        If scrollPosition + barsViewable >= GetIndexChartBar("QQQWWW") Then Exit Sub

        scrollPosition += 1

        PaintChart()
    End Sub

    ''' <summary>
    ''' If the user clicks on the scrollbar, scrolling functions will be called
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>

    Private Sub GanttChart_Click(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseClick
        If e.Button = Windows.Forms.MouseButtons.Left Then
            If mouseOverBottomPart = True Then
                ScrollOneDown()
            ElseIf mouseOverTopPart = True Then
                ScrollOneup()
            End If
        End If
    End Sub

    ''' <summary>
    ''' When mousewheel is used, the scrollbar will scroll
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>

    Private Sub GanttChart_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
        If e.Delta > 0 Then
            ScrollOneup()
        Else
            ScrollOneDown()
        End If
    End Sub

    ''' <summary>
    ''' Mousedrag event
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>

    Public Sub GanttChart_MouseDragged(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDragged
        If mouseOverScrollBarArea = True Then
            ScrollPositionY = e.Location.Y
        End If
    End Sub

#End Region

#Region "Save"

    ''' <summary>
    ''' Saves the GanttChart to specified image file
    ''' </summary>
    ''' <param name="filePath"></param>
    ''' <remarks></remarks>

    Public Sub SaveImage(ByVal filePath As String)
        objGraphics.SmoothingMode = SmoothingMode.HighSpeed
        objGraphics.Clear(Me.BackColor)

        If headerFromDate = Nothing Or headerToDate = Nothing Then Exit Sub

        DrawHeader(objGraphics, Nothing)
        DrawNetHorizontal(objGraphics)
        DrawNetVertical(objGraphics)
        DrawBars(objGraphics, True)

        objBmp.Save(filePath)
    End Sub

#End Region

End Class
 
Código:
 For Each bar As BarInformation In lst

            GanttChartActividades.AddChartBar(bar.RowText, bar, bar.FromTime, bar.ToTime, bar.Color, bar.HoverColor, bar.Index)

        Next
 
Não tinha reparado nisto :S
Vamos lá ver se assim funciona.
Apareceu-me um outro problema de última hora para resolver, por isso se não voltar a postar hoje é normal, amanhã volto ao ataque.
 
Última edição:
Back
Topo