暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. Imports System.Drawing.Drawing2D
  2. ''' <summary>
  3. ''' Adds an easy to use Gantt Chart to your application
  4. ''' Created by Adrian "Adagio" Grau
  5. ''' Version 0.55
  6. ''' </summary>
  7. ''' <remarks></remarks>
  8. Public Class GanttChart
  9. Inherits Control
  10. Private mouseHoverPart As MouseOverPart = MouseOverPart.Empty : Private mouseHoverBarIndex As Integer = -1 : Private bars As New List(Of ChartBarDate)
  11. Private headerFromDate As Date = Nothing : Private headerToDate As Date = Nothing : Private barIsChanging As Integer = -1
  12. Private ReadOnly barStartRight As Integer = 20 : Private barStartLeft As Integer = 100 : Private ReadOnly headerTimeStartTop As Integer = 30
  13. Private shownHeaderList As List(Of Header) : Private ReadOnly barStartTop As Integer = 50 : Private ReadOnly barHeight As Integer = 35
  14. Private ReadOnly barSpace As Integer = 5 : Private widthPerItem As Integer : Private _mouseOverColumnValue As Date = Nothing
  15. Private _mouseOverRowText As String = "" : Private _mouseOverRowValue As Object = Nothing : Private lineColor As Pen = Pens.Bisque
  16. 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)
  17. Private rowTextFont As Font = New Font("VERDANA", 8.0, FontStyle.Regular, GraphicsUnit.Point) : Friend WithEvents ToolTip As New System.Windows.Forms.ToolTip()
  18. Private _allowEditBarWithMouse As Boolean = False : Public Event MouseDragged(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
  19. Public Event BarChanged(ByVal sender As Object, ByRef barValue As Object)
  20. Private objBmp As Bitmap
  21. Private objGraphics As Graphics
  22. #Region "Public properties"
  23. ''' <summary>
  24. ''' Sets to true if the user should be able to manually edit bars
  25. ''' </summary>
  26. ''' <value></value>
  27. ''' <returns></returns>
  28. ''' <remarks></remarks>
  29. Public Property AllowManualEditBar() As Boolean
  30. Get
  31. Return _allowEditBarWithMouse
  32. End Get
  33. Set(ByVal value As Boolean)
  34. _allowEditBarWithMouse = value
  35. End Set
  36. End Property
  37. ''' <summary>
  38. ''' The start date/time of the chart
  39. ''' </summary>
  40. ''' <value></value>
  41. ''' <returns></returns>
  42. ''' <remarks></remarks>
  43. Public Property FromDate() As Date
  44. Get
  45. Return headerFromDate
  46. End Get
  47. Set(ByVal value As Date)
  48. headerFromDate = value
  49. End Set
  50. End Property
  51. ''' <summary>
  52. ''' The end date/time of the chart
  53. ''' </summary>
  54. ''' <value></value>
  55. ''' <returns></returns>
  56. ''' <remarks></remarks>
  57. Public Property ToDate() As Date
  58. Get
  59. Return headerToDate
  60. End Get
  61. Set(ByVal value As Date)
  62. headerToDate = value
  63. End Set
  64. End Property
  65. ''' <summary>
  66. ''' The text for the current row the mouse hovers above
  67. ''' </summary>
  68. ''' <value></value>
  69. ''' <returns></returns>
  70. ''' <remarks></remarks>
  71. Public ReadOnly Property MouseOverRowText() As String
  72. Get
  73. Return _mouseOverRowText
  74. End Get
  75. End Property
  76. ''' <summary>
  77. ''' The value for the current bar the mouse hovers above
  78. ''' </summary>
  79. ''' <value></value>
  80. ''' <returns></returns>
  81. ''' <remarks></remarks>
  82. Public ReadOnly Property MouseOverRowValue() As Object
  83. Get
  84. Return _mouseOverRowValue
  85. End Get
  86. End Property
  87. ''' <summary>
  88. ''' The date/time the mouse hovers above
  89. ''' </summary>
  90. ''' <value></value>
  91. ''' <returns></returns>
  92. ''' <remarks></remarks>
  93. Public ReadOnly Property MouseOverColumnDate() As Date
  94. Get
  95. Return _mouseOverColumnValue
  96. End Get
  97. End Property
  98. ''' <summary>
  99. ''' The color of the grid
  100. ''' </summary>
  101. ''' <value></value>
  102. ''' <returns></returns>
  103. ''' <remarks></remarks>
  104. Public Property GridColor() As System.Drawing.Pen
  105. Get
  106. Return lineColor
  107. End Get
  108. Set(ByVal value As System.Drawing.Pen)
  109. lineColor = value
  110. End Set
  111. End Property
  112. ''' <summary>
  113. ''' The font used for the row text
  114. ''' </summary>
  115. ''' <value></value>
  116. ''' <returns></returns>
  117. ''' <remarks></remarks>
  118. Public Property RowFont() As Font
  119. Get
  120. Return rowTextFont
  121. End Get
  122. Set(ByVal value As Font)
  123. rowTextFont = value
  124. End Set
  125. End Property
  126. ''' <summary>
  127. ''' The font used for the "date" text in the columns
  128. ''' </summary>
  129. ''' <value></value>
  130. ''' <returns></returns>
  131. ''' <remarks></remarks>
  132. Public Property DateFont() As Font
  133. Get
  134. Return dateTextFont
  135. End Get
  136. Set(ByVal value As Font)
  137. dateTextFont = value
  138. End Set
  139. End Property
  140. ''' <summary>
  141. ''' The font used for the "time" text in the colums)
  142. ''' </summary>
  143. ''' <value></value>
  144. ''' <returns></returns>
  145. ''' <remarks></remarks>
  146. Public Property TimeFont() As Font
  147. Get
  148. Return timeTextFont
  149. End Get
  150. Set(ByVal value As Font)
  151. timeTextFont = value
  152. End Set
  153. End Property
  154. #End Region
  155. #Region "Constructor"
  156. ''' <summary>
  157. ''' Default constructor
  158. ''' </summary>
  159. ''' <remarks></remarks>
  160. Public Sub New()
  161. ToolTip.AutoPopDelay = 15000 : ToolTip.InitialDelay = 250 : ToolTip.OwnerDraw = True
  162. objBmp = New Bitmap(1280, 1024, Imaging.PixelFormat.Format24bppRgb) : objGraphics = Graphics.FromImage(objBmp)
  163. ' Flicker free drawing
  164. Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint, True)
  165. End Sub
  166. #End Region
  167. #Region "Bars"
  168. Private Sub SetBarStartLeft(ByVal rowText As String)
  169. Dim gfx As Graphics = Me.CreateGraphics
  170. Dim length As Integer = gfx.MeasureString(rowText, rowTextFont, 500).Width
  171. If length > barStartLeft Then : barStartLeft = length : End If
  172. End Sub
  173. ''' <summary>
  174. ''' Adds a bar to the list
  175. ''' </summary>
  176. ''' <param name="rowText">Text for the row</param>
  177. ''' <param name="barValue">Value for the row</param>
  178. ''' <param name="fromTime">The date/time the bar starts</param>
  179. ''' <param name="toTime">The date/time the bar ends</param>
  180. ''' <param name="color">The color of the bar</param>
  181. ''' <param name="hoverColor">The hover color of the bar</param>
  182. ''' <param name="rowIndex">The rowindex of the bar (useful if you want several bars on the same row)</param>
  183. ''' <remarks></remarks>
  184. Public Sub AddChartBar(ByVal rowText As String, ByVal barValue As Object, ByVal fromTime As Date, ByVal toTime As Date,
  185. ByVal color As Color, ByVal hoverColor As Color, ByVal rowIndex As Integer)
  186. Dim bar As New ChartBarDate With {
  187. .Text = rowText,
  188. .Value = barValue,
  189. .StartValue = fromTime,
  190. .EndValue = toTime,
  191. .Color = color,
  192. .HoverColor = hoverColor,
  193. .RowIndex = rowIndex
  194. } : bars.Add(bar) : SetBarStartLeft(rowText)
  195. End Sub
  196. ''' <summary>
  197. ''' Adds a bar to the list
  198. ''' </summary>
  199. ''' <param name="rowText">Text for the row</param>
  200. ''' <param name="barValue">Value for the row</param>
  201. ''' <param name="fromTime">The date/time the bar starts</param>
  202. ''' <param name="toTime">The date/time the bar ends</param>
  203. ''' <param name="color">The color of the bar</param>
  204. ''' <param name="hoverColor">The hover color of the bar</param>
  205. ''' <param name="rowIndex">The rowindex of the bar (useful if you want several bars on the same row)</param>
  206. ''' <param name="hideFromMouseMove">If you want to "hide" the bar from mousemove event</param>
  207. ''' <remarks></remarks>
  208. Public Sub AddChartBar(ByVal rowText As String, ByVal barValue As Object, ByVal fromTime As Date, ByVal toTime As Date, ByVal color As Color,
  209. ByVal hoverColor As Color, ByVal rowIndex As Integer, ByVal hideFromMouseMove As Boolean)
  210. Dim bar As New ChartBarDate With {
  211. .Text = rowText,
  212. .Value = barValue,
  213. .StartValue = fromTime,
  214. .EndValue = toTime,
  215. .Color = color,
  216. .HoverColor = hoverColor,
  217. .RowIndex = rowIndex,
  218. .HideFromMouseMove = hideFromMouseMove
  219. } : bars.Add(bar) : SetBarStartLeft(rowText)
  220. End Sub
  221. ''' <summary>
  222. ''' Gets the next index
  223. ''' </summary>
  224. ''' <param name="rowText"></param>
  225. ''' <returns></returns>
  226. ''' <remarks></remarks>
  227. Public Function GetIndexChartBar(ByVal rowText As String) As Integer
  228. Dim index As Integer = -1
  229. 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
  230. Return index + 1
  231. End Function
  232. ''' <summary>
  233. ''' Removes all bars from list
  234. ''' </summary>
  235. ''' <remarks></remarks>
  236. Public Sub RemoveBars()
  237. bars = New List(Of ChartBarDate) : barStartLeft = 100
  238. End Sub
  239. #End Region
  240. #Region "Draw"
  241. ''' <summary>
  242. ''' Redraws the Gantt chart
  243. ''' </summary>
  244. ''' <remarks></remarks>
  245. Public Sub PaintChart()
  246. Me.Invalidate()
  247. End Sub
  248. ''' <summary>
  249. ''' Redraws the Gantt chart
  250. ''' </summary>
  251. ''' <param name="gfx"></param>
  252. ''' <remarks></remarks>
  253. Private Sub PaintChart(ByVal gfx As Graphics)
  254. Try
  255. gfx.Clear(Me.BackColor) : If headerFromDate = Nothing Or headerToDate = Nothing Then Exit Sub
  256. DrawScrollBar(gfx) : DrawHeader(gfx, Nothing) : DrawNetHorizontal(gfx) : DrawNetVertical(gfx) : DrawBars(gfx)
  257. objBmp = New Bitmap(Me.Width - barStartRight, lastLineStop, Imaging.PixelFormat.Format24bppRgb)
  258. objGraphics = Graphics.FromImage(objBmp)
  259. Catch ex As Exception
  260. End Try
  261. End Sub
  262. ''' <summary>
  263. ''' Redraws the Gantt chart
  264. ''' </summary>
  265. ''' <param name="pe"></param>
  266. ''' <remarks></remarks>
  267. Protected Overrides Sub OnPaint(ByVal pe As System.Windows.Forms.PaintEventArgs)
  268. MyBase.OnPaint(pe) : PaintChart(pe.Graphics)
  269. End Sub
  270. ''' <summary>
  271. ''' Draws the list of headers. Automatically shows which headers to draw, based on the width of the Gantt Chart
  272. ''' </summary>
  273. ''' <param name="gfx"></param>
  274. ''' <param name="headerList"></param>
  275. ''' <remarks></remarks>
  276. Private Sub DrawHeader(ByVal gfx As Graphics, ByVal headerList As List(Of Header))
  277. If headerList Is Nothing Then : headerList = GetFullHeaderList() : End If
  278. If headerList.Count = 0 Then Exit Sub
  279. Dim availableWidth = Me.Width - 10 - barStartLeft - barStartRight : widthPerItem = availableWidth / headerList.Count
  280. If widthPerItem < 40 Then
  281. Dim newHeaderList As New List(Of Header) : Dim showNext As Boolean = True
  282. ' If there's not enough room for all headers remove 50%
  283. For Each header As Header In headerList : If showNext = True Then : newHeaderList.Add(header) : showNext = False : Else : showNext = True : End If : Next
  284. DrawHeader(gfx, newHeaderList) : Exit Sub
  285. End If
  286. Dim index As Integer = 0 : Dim lastHeader As Header = Nothing ': Dim headerStartPosition As Integer = -1
  287. For Each header As Header In headerList
  288. Dim startPos As Integer = barStartLeft + (index * widthPerItem) : Dim showDateHeader As Boolean = False : header.StartLocation = startPos
  289. ' Checks whether to show the date or not
  290. If lastHeader Is Nothing Then : showDateHeader = True
  291. ElseIf header.Time.Hour < lastHeader.Time.Hour Then : showDateHeader = True
  292. ElseIf header.Time.Minute = lastHeader.Time.Minute Then : showDateHeader = True : End If
  293. ' Show date
  294. If showDateHeader = True Then
  295. Dim str As String = ""
  296. If header.HeaderTextInsteadOfTime.Length > 0 Then : str = header.HeaderTextInsteadOfTime
  297. Else : str = header.Time.ToString("d-MMM") : End If : gfx.DrawString(str, dateTextFont, Brushes.Black, startPos, 0)
  298. End If
  299. ' Show time
  300. gfx.DrawString(header.HeaderText, timeTextFont, Brushes.Black, startPos, headerTimeStartTop) : index += 1 : lastHeader = header
  301. Next
  302. shownHeaderList = headerList : widthPerItem = (Me.Width - 10 - barStartLeft - barStartRight) / shownHeaderList.Count
  303. End Sub
  304. ''' <summary>
  305. ''' Draws the bars
  306. ''' </summary>
  307. ''' <param name="grfx"></param>
  308. ''' <remarks></remarks>
  309. Private Sub DrawBars(ByVal grfx As Graphics, Optional ByVal ignoreScrollAndMousePosition As Boolean = False)
  310. If shownHeaderList Is Nothing Then Exit Sub : If shownHeaderList.Count = 0 Then Exit Sub
  311. Dim index As Integer
  312. ' Finds pixels per minute
  313. Dim timeBetween As TimeSpan = shownHeaderList(1).Time - shownHeaderList(0).Time
  314. Dim minutesBetween As Integer = CInt(timeBetween.TotalMinutes) '(timeBetween.Days * 1440) + (timeBetween.Hours * 60) + timeBetween.Minutes
  315. Dim widthBetween = (shownHeaderList(1).StartLocation - shownHeaderList(0).StartLocation) : Dim perMinute As Decimal = widthBetween / minutesBetween
  316. ' Draws each bar
  317. For Each bar As ChartBarDate In bars
  318. index = bar.RowIndex : Dim startLocation As Integer : Dim width As Integer : Dim startMinutes As Integer ' Number of minutes from start of the gantt chart
  319. Dim startTimeSpan As TimeSpan : Dim lengthMinutes As Integer ' Number of minutes from bar start to bar end
  320. Dim lengthTimeSpan As TimeSpan : Dim scrollPos As Integer = 0
  321. If ignoreScrollAndMousePosition = False Then : scrollPos = scrollPosition : End If
  322. ' Calculates where the bar should be located
  323. startTimeSpan = bar.StartValue - FromDate : startMinutes = (startTimeSpan.Days * 1440) + (startTimeSpan.Hours * 60) + startTimeSpan.Minutes
  324. startLocation = perMinute * startMinutes : Dim endValue As Date = bar.EndValue
  325. If endValue = Nothing Then : endValue = Date.Now : End If
  326. lengthTimeSpan = endValue - bar.StartValue : lengthMinutes = (lengthTimeSpan.Days * 1440) + (lengthTimeSpan.Hours * 60) + lengthTimeSpan.Minutes
  327. width = perMinute * lengthMinutes
  328. Dim a As Integer = barStartLeft + startLocation : Dim b As Integer = barStartTop + (barHeight * (index - scrollPos)) + (barSpace * (index - scrollPos)) + 2
  329. Dim c As Integer = width : Dim d As Integer = barHeight
  330. If c = 0 Then c = 1 ' Stops a bar from going into the row-text area
  331. If a - barStartLeft < 0 Then : a = barStartLeft : End If
  332. Dim color As System.Drawing.Color
  333. ' If mouse is over bar, set the color to be hovercolor
  334. If MouseOverRowText = bar.Text And bar.StartValue <= _mouseOverColumnValue And bar.EndValue >= _mouseOverColumnValue Then
  335. color = bar.HoverColor : Else : color = bar.Color : End If
  336. ' Set the location for the graphics
  337. bar.TopLocation.Left = New Point(a, b) : bar.TopLocation.Right = New Point(a + c, b) : bar.BottomLocation.Left = New Point(a, b + d)
  338. bar.BottomLocation.Right = New Point(a, b + d)
  339. Dim obBrush As LinearGradientBrush : Dim obRect As New Rectangle(a, b, c, d)
  340. If bar.StartValue <> Nothing And endValue <> Nothing Then
  341. If (index >= scrollPos And index < barsViewable + scrollPos) Or ignoreScrollAndMousePosition = True Then ' Makes the bar gradient
  342. obBrush = New LinearGradientBrush(obRect, color, Color.Gray, LinearGradientMode.Vertical) ' Draws the bar
  343. grfx.DrawRectangle(Pens.Black, obRect) : grfx.FillRectangle(obBrush, obRect) ' Draws the rowtext
  344. grfx.DrawString(bar.Text, rowTextFont, Brushes.Black, 0, barStartTop + (barHeight * (index - scrollPos)) + (barSpace * (index - scrollPos)))
  345. obBrush = Nothing : obRect = Nothing : obBrush = Nothing
  346. End If
  347. End If : color = Nothing
  348. Next
  349. End Sub
  350. ''' <summary>
  351. ''' Draws the vertical lines
  352. ''' </summary>
  353. ''' <param name="grfx"></param>
  354. ''' <remarks></remarks>
  355. Public Sub DrawNetVertical(ByVal grfx As Graphics)
  356. If shownHeaderList Is Nothing Then Exit Sub : If shownHeaderList.Count = 0 Then Exit Sub
  357. Dim index As Integer = 0 : Dim availableWidth As Integer = Me.Width - 10 - barStartLeft - barStartRight : Dim lastHeader As Header = Nothing
  358. For Each header As Header In shownHeaderList
  359. Dim headerLocationY As Integer = 0
  360. If lastHeader Is Nothing Then : headerLocationY = 0 : ElseIf header.Time.Hour < lastHeader.Time.Hour Then : headerLocationY = 0 : Else : headerLocationY = headerTimeStartTop : End If
  361. grfx.DrawLine(Pens.Bisque, barStartLeft + (index * widthPerItem), headerLocationY, barStartLeft + (index * widthPerItem), lastLineStop) : index += 1 : lastHeader = header
  362. Next
  363. grfx.DrawLine(lineColor, barStartLeft + (index * widthPerItem), headerTimeStartTop, barStartLeft + (index * widthPerItem), lastLineStop)
  364. End Sub
  365. ''' <summary>
  366. ''' Draws the horizontal lines
  367. ''' </summary>
  368. ''' <param name="grfx"></param>
  369. ''' <remarks></remarks>
  370. Public Sub DrawNetHorizontal(ByVal grfx As Graphics)
  371. If shownHeaderList Is Nothing Then Exit Sub : If shownHeaderList.Count = 0 Then Exit Sub
  372. Dim index As Integer : Dim width As Integer = (widthPerItem * shownHeaderList.Count) + barStartLeft
  373. For index = 0 To GetIndexChartBar("QQQQQQ") ' Last used index. Hopefully nobody will make a row named QQQ :o)
  374. For Each bar As ChartBarDate In bars
  375. grfx.DrawLine(lineColor, 0, barStartTop + (barHeight * index) + (barSpace * index), width, barStartTop + (barHeight * index) + (barSpace * index))
  376. Next
  377. Next : lastLineStop = barStartTop + (barHeight * (index - 1)) + (barSpace * (index - 1))
  378. End Sub ' This is the position (in pixels, from top) of the last line. Used for drawing lines
  379. Private lastLineStop As Integer = 0
  380. #End Region
  381. #Region "Header list"
  382. ''' <summary>
  383. ''' Gets the full header list, consisting of hours between the two dates set
  384. ''' </summary>
  385. ''' <returns></returns>
  386. ''' <remarks></remarks>
  387. Private Function GetFullHeaderList() As List(Of Header)
  388. 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
  389. If interval.TotalDays < 1 Then
  390. With newFromTime
  391. newFromTime = .AddHours(FromDate.Hour)
  392. If headerFromDate.Minute < 59 And headerFromDate.Minute > 29 Then : newFromTime = .AddMinutes(30) : Else : newFromTime = .AddMinutes(0) : End If
  393. End With
  394. While newFromTime <= ToDate
  395. item = newFromTime.Hour & ":" : If newFromTime.Minute < 10 Then : item += "0" & newFromTime.Minute : Else : item += "" & newFromTime.Minute : End If
  396. Dim header As New Header With {
  397. .HeaderText = item,
  398. .HeaderTextInsteadOfTime = "",
  399. .Time = New Date(newFromTime.Year, newFromTime.Month, newFromTime.Day, newFromTime.Hour, newFromTime.Minute, 0)
  400. } : result.Add(header) : newFromTime = newFromTime.AddMinutes(5) ' The minimum interval of time between the headers
  401. End While
  402. ElseIf interval.TotalDays < 60 Then
  403. While newFromTime <= ToDate
  404. Dim header As New Header With {
  405. .HeaderText = "",
  406. .HeaderTextInsteadOfTime = "",
  407. .Time = New Date(newFromTime.Year, newFromTime.Month, newFromTime.Day, 0, 0, 0)
  408. } : result.Add(header) : newFromTime = newFromTime.AddDays(1) ' The minimum interval of time between the headers
  409. End While
  410. Else
  411. While newFromTime <= ToDate
  412. Dim header As New Header With {
  413. .HeaderText = "",
  414. .Time = New Date(newFromTime.Year, newFromTime.Month, newFromTime.Day, 0, 0, 0),
  415. .HeaderTextInsteadOfTime = newFromTime.ToString("MMM")
  416. } : result.Add(header) : newFromTime = newFromTime.AddMonths(1) ' The minimum interval of time between the headers
  417. End While
  418. End If : Return result
  419. End Function
  420. #End Region
  421. #Region "Mouse Move"
  422. ''' <summary>
  423. ''' Finds the current row and column based on mouse position
  424. ''' </summary>
  425. ''' <param name="sender"></param>
  426. ''' <param name="e"></param>
  427. ''' <remarks></remarks>
  428. Private Sub GanttChart_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
  429. If shownHeaderList Is Nothing Then Exit Sub : If shownHeaderList.Count = 0 Then Exit Sub
  430. If e.Button <> Windows.Forms.MouseButtons.Left Then : mouseHoverPart = MouseOverPart.Empty
  431. ' If bar has changed manually, but left mouse button is no longer pressed the BarChanged event will be raised
  432. If AllowManualEditBar = True Then : If barIsChanging >= 0 Then : RaiseEvent BarChanged(Me, bars(barIsChanging).Value) : barIsChanging = -1 : End If : End If
  433. End If
  434. mouseHoverBarIndex = -1 : Dim LocalMousePosition As Point
  435. LocalMousePosition = Me.PointToClient(Cursor.Position) ' Finds pixels per minute
  436. Dim timeBetween As TimeSpan = shownHeaderList(1).Time - shownHeaderList(0).Time : Dim minutesBetween As Integer = (timeBetween.Days * 1440) + (timeBetween.Hours * 60) + timeBetween.Minutes
  437. Dim widthBetween = (shownHeaderList(1).StartLocation - shownHeaderList(0).StartLocation) : Dim perMinute As Decimal = widthBetween / minutesBetween
  438. ' Finds the time at mousepointer
  439. Dim minutesAtCursor As Integer
  440. If LocalMousePosition.X > barStartLeft Then : minutesAtCursor = (LocalMousePosition.X - barStartLeft) / perMinute : _mouseOverColumnValue = FromDate.AddMinutes(minutesAtCursor)
  441. Else : _mouseOverColumnValue = Nothing : End If ' Finds the row at mousepointer
  442. 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
  443. Dim scrollBarStatusChanged As Boolean = False ' Tests to see if the mouse is hovering over the scroll-area bottom-arrow
  444. If LocalMousePosition.X > BottomPart.Left And LocalMousePosition.Y < BottomPart.Right And LocalMousePosition.Y < BottomPart.Bottom And LocalMousePosition.Y > BottomPart.Top Then
  445. If mouseOverBottomPart = False Then : scrollBarStatusChanged = True : End If : mouseOverBottomPart = True
  446. Else : If mouseOverBottomPart = False Then : scrollBarStatusChanged = True : End If : mouseOverBottomPart = False : End If
  447. ' Tests to see if the mouse is hovering over the scroll-area top-arrow
  448. If LocalMousePosition.X > topPart.Left And LocalMousePosition.Y < topPart.Right And LocalMousePosition.Y < topPart.Bottom And LocalMousePosition.Y > topPart.Top Then
  449. If mouseOverTopPart = False Then : scrollBarStatusChanged = True : End If : mouseOverTopPart = True
  450. Else : If mouseOverTopPart = False Then : scrollBarStatusChanged = True : End If : mouseOverTopPart = False : End If
  451. ' Tests to see if the mouse is hovering over the scroll
  452. If LocalMousePosition.X > scroll.Left And LocalMousePosition.Y < scroll.Right And LocalMousePosition.Y < scroll.Bottom And LocalMousePosition.Y > scroll.Top Then
  453. If mouseOverScrollBar = False Then : scrollBarStatusChanged = True : End If : mouseOverScrollBar = True : mouseOverScrollBarArea = True
  454. Else
  455. If mouseOverScrollBar = False Then : scrollBarStatusChanged = True : End If : mouseOverScrollBar = False : mouseOverScrollBarArea = False
  456. End If
  457. ' 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)
  458. If mouseOverScrollBarArea = False Then
  459. If LocalMousePosition.X > scrollBarArea.Left And LocalMousePosition.Y < scrollBarArea.Right And LocalMousePosition.Y < scrollBarArea.Bottom And LocalMousePosition.Y > scrollBarArea.Top Then
  460. mouseOverScrollBarArea = True
  461. End If
  462. End If ' Tests to see if the mouse pointer is hovering above a bar
  463. Dim index As Integer = 0
  464. For Each bar As ChartBarDate In bars
  465. ' If the bar is set to be hidden from mouse move, the current bar will be ignored
  466. If bar.HideFromMouseMove = False Then
  467. If bar.EndValue = Nothing Then : bar.EndValue = Date.Now : End If
  468. ' Mouse pointer needs to be inside the X and Y positions of the bar
  469. If LocalMousePosition.Y > bar.TopLocation.Left.Y And LocalMousePosition.Y < bar.BottomLocation.Left.Y Then
  470. If LocalMousePosition.X > bar.TopLocation.Left.X And LocalMousePosition.X < bar.TopLocation.Right.X Then
  471. ' If the current bar is the one where the mouse is above, the rowText and rowValue needs to be set correctly
  472. rowText = bar.Text : rowValue = bar.Value : mouseHoverBarIndex = index
  473. If mouseHoverPart <> MouseOverPart.BarLeftSide And mouseHoverPart <> MouseOverPart.BarRightSide Then : mouseHoverPart = MouseOverPart.Bar : End If
  474. End If
  475. ' If mouse pointer is near the edges of the bar it will open up for editing the bar
  476. If AllowManualEditBar = True Then
  477. Dim areaSize As Integer = 5 : If e.Button = Windows.Forms.MouseButtons.Left Then : areaSize = 50 : End If
  478. If LocalMousePosition.X > bar.TopLocation.Left.X - areaSize And LocalMousePosition.X < bar.TopLocation.Left.X + areaSize And mouseHoverPart <> MouseOverPart.BarRightSide Then
  479. Me.Cursor = Cursors.VSplit : mouseHoverPart = MouseOverPart.BarLeftSide : mouseHoverBarIndex = index
  480. ElseIf LocalMousePosition.X > bar.TopLocation.Right.X - areaSize And LocalMousePosition.X < bar.TopLocation.Right.X + areaSize And mouseHoverPart <> MouseOverPart.BarLeftSide Then
  481. Me.Cursor = Cursors.VSplit : mouseHoverPart = MouseOverPart.BarRightSide : mouseHoverBarIndex = index
  482. Else : Me.Cursor = Cursors.Default : End If
  483. End If
  484. End If
  485. End If : index += 1
  486. Next ' Sets the mouseover row value and text
  487. _mouseOverRowText = rowText : _mouseOverRowValue = rowValue
  488. If e.Button = Windows.Forms.MouseButtons.Left Then : RaiseEvent MouseDragged(sender, e) : Else
  489. ' A simple test to see if the mousemovement has caused any changes to how it should be displayed
  490. ' It only redraws if mouse moves from a bar to blank area or from blank area to a bar
  491. ' This increases performance compared to having a redraw every time a mouse moves
  492. 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
  493. End If
  494. End Sub
  495. ''' <summary>
  496. ''' Mouse leave event
  497. ''' </summary>
  498. ''' <param name="sender"></param>
  499. ''' <param name="e"></param>
  500. ''' <remarks></remarks>
  501. Private Sub GanttChart_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.MouseLeave
  502. _mouseOverRowText = Nothing : _mouseOverRowValue = Nothing : mouseHoverPart = MouseOverPart.Empty : PaintChart()
  503. End Sub
  504. ''' <summary>
  505. ''' Mouse drag event
  506. ''' </summary>
  507. ''' <param name="sender"></param>
  508. ''' <param name="e"></param>
  509. ''' <remarks></remarks>
  510. Public Sub GanttChart_MouseDragged(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDragged
  511. If mouseOverScrollBarArea = True Then : ScrollPositionY = e.Location.Y : End If
  512. If AllowManualEditBar = True Then
  513. If mouseHoverBarIndex > -1 Then
  514. If mouseHoverPart = MouseOverPart.BarLeftSide Then : barIsChanging = mouseHoverBarIndex : bars(mouseHoverBarIndex).StartValue = _mouseOverColumnValue : PaintChart()
  515. ElseIf mouseHoverPart = MouseOverPart.BarRightSide Then : barIsChanging = mouseHoverBarIndex : bars(mouseHoverBarIndex).EndValue = _mouseOverColumnValue : PaintChart() : End If
  516. End If
  517. End If
  518. End Sub
  519. #End Region
  520. #Region "ToolTipText"
  521. Private _toolTipText As New List(Of String) : Private _toolTipTextTitle As String = "" : Private MyPoint As New Point(0, 0)
  522. ''' <summary>
  523. ''' The title to draw
  524. ''' </summary>
  525. ''' <value></value>
  526. ''' <returns></returns>
  527. ''' <remarks></remarks>
  528. Public Property ToolTipTextTitle() As String
  529. Get
  530. Return _toolTipTextTitle
  531. End Get
  532. Set(ByVal value As String)
  533. _toolTipTextTitle = value
  534. End Set
  535. End Property
  536. ''' <summary>
  537. ''' Gets or sets the ToolTipText lines
  538. ''' </summary>
  539. ''' <value></value>
  540. ''' <returns></returns>
  541. ''' <remarks>Don not use the add function directly on this, use ToolTipText = value</remarks>
  542. Public Property ToolTipText() As List(Of String)
  543. Get
  544. If _toolTipText Is Nothing Then _toolTipText = New List(Of String) :
  545. Return _toolTipText
  546. End Get
  547. Set(ByVal value As List(Of String))
  548. _toolTipText = value : Dim LocalMousePosition As Point : LocalMousePosition = Me.PointToClient(Cursor.Position)
  549. If LocalMousePosition = MyPoint Then Exit Property : MyPoint = LocalMousePosition : ToolTip.SetToolTip(Me, ".")
  550. End Set
  551. End Property
  552. ''' <summary>
  553. ''' Draws the ToolTip window
  554. ''' </summary>
  555. ''' <param name="sender"></param>
  556. ''' <param name="e"></param>
  557. ''' <remarks></remarks>
  558. Private Sub ToolTipText_Draw(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawToolTipEventArgs) Handles ToolTip.Draw
  559. If ToolTipText Is Nothing Then : ToolTipText = New List(Of String) : Exit Sub : End If
  560. If ToolTipText.Count = 0 Then : Exit Sub : ElseIf ToolTipText(0).Length = 0 Then : Exit Sub : End If
  561. Dim x As Integer : Dim y As Integer
  562. e.Graphics.FillRectangle(Brushes.AntiqueWhite, e.Bounds) : e.DrawBorder()
  563. Dim titleHeight As Integer = 14 : Dim fontHeight As Integer = 12
  564. ' Draws the line just below the title
  565. e.Graphics.DrawLine(Pens.Black, 0, titleHeight, e.Bounds.Width, titleHeight)
  566. Dim lines As Integer = 1 : Dim text As String = ToolTipTextTitle ' Draws the title
  567. Using font As New Font(e.Font, FontStyle.Bold)
  568. x = (e.Bounds.Width - e.Graphics.MeasureString(text, font).Width) \ 2 : y = (titleHeight - e.Graphics.MeasureString(text, font).Height) \ 2
  569. e.Graphics.DrawString(text, font, Brushes.Black, x, y)
  570. End Using ' Draws the lines
  571. For Each str As String In ToolTipText
  572. Dim font As New Font(e.Font, FontStyle.Regular)
  573. If str.Contains("[b]") Then : font = New Font(font.FontFamily, font.Size, FontStyle.Bold, font.Unit) : str = str.Replace("[b]", "") : End If
  574. Using font
  575. x = 5 : y = (titleHeight - fontHeight - e.Graphics.MeasureString(str, font).Height) \ 2 + 10 + (lines * 14) : e.Graphics.DrawString(str, font, Brushes.Black, x, y)
  576. End Using : lines += 1
  577. Next
  578. End Sub
  579. ''' <summary>
  580. ''' Automatically resizes the ToolTip window
  581. ''' </summary>
  582. ''' <param name="sender"></param>
  583. ''' <param name="e"></param>
  584. ''' <remarks></remarks>
  585. Private Sub ToolTipText_Popup(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PopupEventArgs) Handles ToolTip.Popup
  586. If ToolTipText Is Nothing Then : ToolTipText = New List(Of String) : End If
  587. If ToolTipText.Count = 0 Then : e.ToolTipSize = New Size(0, 0) : Exit Sub
  588. ElseIf ToolTipText(0).Length = 0 Then : e.ToolTipSize = New Size(0, 0) : Exit Sub : End If ' resizes the ToolTip window
  589. Dim height As Integer = 18 + (ToolTipText.Count * 15) : e.ToolTipSize = New Size(200, height)
  590. End Sub
  591. #End Region
  592. #Region "ChartBar"
  593. Private Class ChartBarDate
  594. Friend Class Location
  595. Private _right As New Point(0, 0) : Private _left As New Point(0, 0)
  596. Public Property Right() As Point
  597. Get
  598. Return _right
  599. End Get
  600. Set(ByVal value As Point)
  601. _right = value
  602. End Set
  603. End Property
  604. Public Property Left() As Point
  605. Get
  606. Return _left
  607. End Get
  608. Set(ByVal value As Point)
  609. _left = value
  610. End Set
  611. End Property
  612. End Class
  613. Private _startValue As Date : Private _endValue As Date : Private _color As Color : Private _hoverColor As Color : Private _text As String
  614. Private _value As Object : Private _rowIndex As Integer : Private _topLocation As New Location : Private _bottomLocation As New Location
  615. Private _hideFromMouseMove As Boolean = False
  616. Public Property StartValue() As Date
  617. Get
  618. Return _startValue
  619. End Get
  620. Set(ByVal value As Date)
  621. _startValue = value
  622. End Set
  623. End Property
  624. Public Property EndValue() As Date
  625. Get
  626. Return _endValue
  627. End Get
  628. Set(ByVal value As Date)
  629. _endValue = value
  630. End Set
  631. End Property
  632. Public Property Color() As Color
  633. Get
  634. Return _color
  635. End Get
  636. Set(ByVal value As Color)
  637. _color = value
  638. End Set
  639. End Property
  640. Public Property HoverColor() As Color
  641. Get
  642. Return _hoverColor
  643. End Get
  644. Set(ByVal value As Color)
  645. _hoverColor = value
  646. End Set
  647. End Property
  648. Public Property Text() As String
  649. Get
  650. Return _text
  651. End Get
  652. Set(ByVal value As String)
  653. _text = value
  654. End Set
  655. End Property
  656. Public Property Value() As Object
  657. Get
  658. Return _value
  659. End Get
  660. Set(ByVal value As Object)
  661. _value = value
  662. End Set
  663. End Property
  664. Public Property RowIndex() As Integer
  665. Get
  666. Return _rowIndex
  667. End Get
  668. Set(ByVal value As Integer)
  669. _rowIndex = value
  670. End Set
  671. End Property
  672. Public Property HideFromMouseMove() As Boolean
  673. Get
  674. Return _hideFromMouseMove
  675. End Get
  676. Set(ByVal value As Boolean)
  677. _hideFromMouseMove = value
  678. End Set
  679. End Property
  680. Friend Property TopLocation() As Location
  681. Get
  682. Return _topLocation
  683. End Get
  684. Set(ByVal value As Location)
  685. _topLocation = value
  686. End Set
  687. End Property
  688. Friend Property BottomLocation() As Location
  689. Get
  690. Return _bottomLocation
  691. End Get
  692. Set(ByVal value As Location)
  693. _bottomLocation = value
  694. End Set
  695. End Property
  696. End Class
  697. #End Region
  698. #Region "Headers"
  699. Private Class Header
  700. Private _headerText As String
  701. Private _startLocation As Integer
  702. Private _headerTextInsteadOfTime As String = ""
  703. Private _time As Date = Nothing
  704. Public Property HeaderText() As String
  705. Get
  706. Return _headerText
  707. End Get
  708. Set(ByVal value As String)
  709. _headerText = value
  710. End Set
  711. End Property
  712. Public Property StartLocation() As Integer
  713. Get
  714. Return _startLocation
  715. End Get
  716. Set(ByVal value As Integer)
  717. _startLocation = value
  718. End Set
  719. End Property
  720. ''' <summary>
  721. ''' If this string is larger than 0, this will be used instead of Time
  722. ''' </summary>
  723. ''' <value></value>
  724. ''' <returns></returns>
  725. ''' <remarks></remarks>
  726. Public Property HeaderTextInsteadOfTime() As String
  727. Get
  728. Return _headerTextInsteadOfTime
  729. End Get
  730. Set(ByVal value As String)
  731. _headerTextInsteadOfTime = value
  732. End Set
  733. End Property
  734. ''' <summary>
  735. ''' Time to display
  736. ''' </summary>
  737. ''' <value></value>
  738. ''' <returns></returns>
  739. ''' <remarks></remarks>
  740. Public Property Time() As Date
  741. Get
  742. Return _time
  743. End Get
  744. Set(ByVal value As Date)
  745. _time = value
  746. End Set
  747. End Property
  748. End Class
  749. #End Region
  750. #Region "Resize"
  751. ''' <summary>
  752. ''' On resize the Gantt Chart is redrawn
  753. ''' </summary>
  754. ''' <param name="e"></param>
  755. ''' <remarks></remarks>
  756. Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
  757. Try
  758. MyBase.OnResize(e) : scrollPosition = 0 ' Used for when the Gantt Chart is saved as an image
  759. If lastLineStop > 0 Then : objBmp = New Bitmap(Me.Width - barStartRight, lastLineStop, Imaging.PixelFormat.Format32bppRgb) : objGraphics = Graphics.FromImage(objBmp) : End If
  760. PaintChart()
  761. Catch ex As Exception
  762. End Try
  763. End Sub
  764. #End Region
  765. #Region "Scrollbar"
  766. Private barsViewable As Integer = -1 : Private scrollPosition As Integer = 0 : Private topPart As Rectangle = Nothing : Private BottomPart As Rectangle = Nothing
  767. Private scroll As Rectangle = Nothing : Private scrollBarArea As Rectangle = Nothing : Private mouseOverTopPart As Boolean = False
  768. Private mouseOverBottomPart As Boolean = False : Private mouseOverScrollBar As Boolean = False : Private mouseOverScrollBarArea As Boolean = False
  769. ''' <summary>
  770. ''' Draws a scrollbar to the component, if there's a need for it
  771. ''' </summary>
  772. ''' <param name="grfx"></param>
  773. ''' <remarks></remarks>
  774. Private Sub DrawScrollBar(ByVal grfx As Graphics)
  775. barsViewable = (Me.Height - barStartTop) / (barHeight + barSpace) : Dim barCount As Integer = GetIndexChartBar("QQQWWW")
  776. If barCount = 0 Then Exit Sub
  777. Dim maxHeight As Integer = Me.Height - 30 : Dim scrollHeight As Decimal = (maxHeight / barCount) * barsViewable
  778. ' If the scroll area is filled there's no need to show the scrollbar
  779. If scrollHeight >= maxHeight Then Exit Sub
  780. Dim scrollSpeed As Decimal = (maxHeight - scrollHeight) / (barCount - barsViewable) : scrollBarArea = New Rectangle(Me.Width - 20, 19, 12, maxHeight)
  781. scroll = New Rectangle(Me.Width - 20, 19 + (scrollPosition * scrollSpeed), 12, scrollHeight)
  782. topPart = New Rectangle(Me.Width - 20, 10, 12, 8) : BottomPart = New Rectangle(Me.Width - 20, Me.Height - 10, 12, 8)
  783. Dim colorTopPart As Brush : Dim colorBottomPart As Brush : Dim colorScroll As Brush
  784. If mouseOverTopPart = True Then : colorTopPart = Brushes.Black : Else : colorTopPart = Brushes.Gray : End If
  785. If mouseOverBottomPart = True Then : colorBottomPart = Brushes.Black : Else : colorBottomPart = Brushes.Gray : End If
  786. If mouseOverScrollBar = True Then : colorScroll = New LinearGradientBrush(scroll, Color.Bisque, Color.Gray, LinearGradientMode.Horizontal)
  787. Else : colorScroll = New LinearGradientBrush(scroll, Color.White, Color.Gray, LinearGradientMode.Horizontal) : End If ' Draws the top and bottom part of the scrollbar
  788. grfx.DrawRectangle(Pens.Black, topPart) : grfx.FillRectangle(Brushes.LightGray, topPart) : grfx.DrawRectangle(Pens.Black, BottomPart) : grfx.FillRectangle(Brushes.LightGray, BottomPart)
  789. ' Draws arrows
  790. Dim points(2) As PointF : points(0) = New PointF(topPart.Left, topPart.Bottom - 1) : points(1) = New PointF(topPart.Right, topPart.Bottom - 1)
  791. 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)
  792. points(1) = New PointF(BottomPart.Right, BottomPart.Top + 1) : points(2) = New PointF((BottomPart.Left + BottomPart.Right) / 2, BottomPart.Bottom - 1)
  793. grfx.FillPolygon(colorBottomPart, points)
  794. ' Draws the scroll area
  795. grfx.DrawRectangle(Pens.Black, scrollBarArea) : grfx.FillRectangle(Brushes.DarkGray, scrollBarArea)
  796. ' Draws the actual scrollbar
  797. grfx.DrawRectangle(Pens.Black, scroll) : grfx.FillRectangle(colorScroll, scroll)
  798. End Sub
  799. ''' <summary>
  800. ''' The Y-position of the center of the scroll
  801. ''' </summary>
  802. ''' <value></value>
  803. ''' <returns></returns>
  804. ''' <remarks></remarks>
  805. Private Property ScrollPositionY() As Integer
  806. Get
  807. If scroll = Nothing Then Return -1 :
  808. Return ((scroll.Height / 2) + scroll.Location.Y) + 19
  809. End Get
  810. Set(ByVal value As Integer)
  811. Dim barCount As Integer = GetIndexChartBar("QQQWWW") : Dim maxHeight As Integer = Me.Height - 30
  812. Dim scrollHeight As Decimal = (maxHeight / barCount) * barsViewable : Dim scrollSpeed As Decimal = (maxHeight - scrollHeight) / (barCount - barsViewable)
  813. Dim index As Integer = 0 : Dim distanceFromLastPosition = 9999 ' Tests to see what scrollposition is the closest to the set position
  814. While index < barCount
  815. Dim newPositionTemp As Integer = (index * scrollSpeed) + (scrollHeight / 2) + (30 / 2) : Dim distanceFromCurrentPosition = newPositionTemp - value
  816. If distanceFromLastPosition < 0 Then
  817. If distanceFromCurrentPosition < distanceFromLastPosition Then : scrollPosition = index - 1 : PaintChart() : Exit Property : End If
  818. Else
  819. If distanceFromCurrentPosition > distanceFromLastPosition Then : scrollPosition = index - 1 ' A precaution to make sure the scroll bar doesn't go too far down
  820. If scrollPosition + barsViewable > GetIndexChartBar("QQQWWW") Then : scrollPosition = GetIndexChartBar("QQQWWW") - barsViewable : End If
  821. PaintChart() : Exit Property
  822. End If
  823. End If : distanceFromLastPosition = distanceFromCurrentPosition : index += 1
  824. End While
  825. End Set
  826. End Property
  827. ''' <summary>
  828. ''' Scrolls one row up
  829. ''' </summary>
  830. ''' <remarks></remarks>
  831. Public Sub ScrollOneup()
  832. If scrollPosition = 0 Then Exit Sub : scrollPosition -= 1 : PaintChart()
  833. End Sub
  834. ''' <summary>
  835. ''' Scrolls one row down
  836. ''' </summary>
  837. ''' <remarks></remarks>
  838. Public Sub ScrollOneDown()
  839. If scrollPosition + barsViewable >= GetIndexChartBar("QQQWWW") Then Exit Sub : scrollPosition += 1 : PaintChart()
  840. End Sub
  841. ''' <summary>
  842. ''' If the user clicks on the scrollbar, scrolling functions will be called
  843. ''' </summary>
  844. ''' <param name="sender"></param>
  845. ''' <param name="e"></param>
  846. ''' <remarks></remarks>
  847. Private Sub GanttChart_Click(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseClick
  848. If e.Button = Windows.Forms.MouseButtons.Left Then : If mouseOverBottomPart = True Then : ScrollOneDown() : ElseIf mouseOverTopPart = True Then : ScrollOneup() : End If : End If
  849. End Sub
  850. ''' <summary>
  851. ''' When mousewheel is used, the scrollbar will scroll
  852. ''' </summary>
  853. ''' <param name="sender"></param>
  854. ''' <param name="e"></param>
  855. ''' <remarks></remarks>
  856. Private Sub GanttChart_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
  857. If e.Delta > 0 Then : ScrollOneup() : Else : ScrollOneDown() : End If
  858. End Sub
  859. #End Region
  860. #Region "Save"
  861. ''' <summary>
  862. ''' Saves the GanttChart to specified image file
  863. ''' </summary>
  864. ''' <param name="filePath"></param>
  865. ''' <remarks></remarks>
  866. Public Sub SaveImage(ByVal filePath As String)
  867. objGraphics.SmoothingMode = SmoothingMode.HighSpeed : objGraphics.Clear(Me.BackColor) : If headerFromDate = Nothing Or headerToDate = Nothing Then Exit Sub
  868. DrawHeader(objGraphics, Nothing) : DrawNetHorizontal(objGraphics) : DrawNetVertical(objGraphics) : DrawBars(objGraphics, True) : objBmp.Save(filePath)
  869. End Sub
  870. #End Region
  871. Private Enum MouseOverPart
  872. Empty
  873. Bar
  874. BarLeftSide
  875. BarRightSide
  876. End Enum
  877. End Class