在单元格绘制甘特图

上一节已经讲到,DrawCell事件可以直接使用GDI+绘图。
在此基础上,本节内容讲述如何用DrawCell事件绘制甘特图。
由于是自己编码绘制,所以会比普通的甘特图控件更加灵活,可以附加很多其他的功能。

本节内容可以参考CaseStudy目录下的文件:编码绘制甘特图.Table

该文件实现了以下功能:

1、左表显示任务,右表显示甘特图。
2、甘特图表的结构,是根据任务表的开始日期和结束日期范围自动生成的。
3、上下滚动任务表,甘特图表会同步滚动,反之亦然。
4、选择某个任务,会同步选择此任务的甘特图,反之亦然。
5、在任务表进筛选后,能够根据筛选后的日期范围,重新生成甘特图表的结构。
6、甘特图以绿色表示过去的日期,以红色表示未来的日期。

相关知识要点:AfterScroll  ScrollPosition 可见区域  GDI+快速入门

设计步骤

1、新建一个窗口,窗口类型设置为主窗口。
2、再插入一个SplitContainer(分区面板),停靠属性设置为Fill。
3、在分区面板的左分区插入一个Table控件,绑定到任务表,停靠属性设置为Fill,名称为Table1。
4、在分区面板的右分区插入一个Table控件,类型设置为SQLTable,停靠属性设置为Fill,名称为Table2。
5、在全局代码中定义一个Public变量:

Public DrawGannt As Boolean = True

DrawGannt相当于一个开关,将其设置为True,正常绘制甘特图,将其设置为False,暂停绘制甘特图。

6、自定义内部函数,分别为:

函数名 说明 代码
BuildGanttTable
根据任务表生成甘特图表的结构。

 

Dim tbl As Table = Tables("任务")

Tables("窗口1_Table2").StopRedraw()

Dim StartDate As Date = tbl.Compute("Min(开始日期)")

Dim EndDate As Date = tbl.Compute("Max(结束日期)")

Dim dt As Date = StartDate

Dim Builder As New DataTableBuilder("统计")

Do

    Dim nm As String = dt.Year & "年" &  dt.Month & "月_" & dt.Day

    Builder.Adddef(nm,Gettype(String),1)

    dt = dt.Adddays(1)

    If dt > Enddate Then

        Exit Do

    End If

Loop

Tables("窗口1_Table2").DataSource = Builder.BuildDataSource

For Each cl As Col In Tables("窗口1_Table2").Cols

    cl.width = 20

Next

Functions.Execute("AddGanttRows")

Tables("窗口1_Table2").ResumeRedraw()

AddGanttRows 根据任务表的行数在甘特图表添加对应的行数。

Dim tbl As DataTable = DataTables("窗口1_Table2")
tbl
.StopRedraw
tbl
.DataRows.Clear()
For
 i As Integer = 1 To Tables("任务").Rows.Count
    
tbl.AddNew()
Next

tbl
.Save()
tbl
.ResumeRedraw

SetGanntLeftCol 设置甘特图表左边第一个可见列,使得甘特图表的自动左右滚动,确保任务表第一个可见任务的甘特图可见。

If Forms("窗口1").Opened()
    
Dim t1 As Table = Tables("任务")
    
Dim t2 As Table = Tables("窗口1_Table2")
    
If t1.TopVisibleRow >=0 Then
        
Dim r As Row = t1.Rows(t1.TopVisibleRow)
        
Dim dt As Date = r("开始日期")
        
Dim nm As String = dt.Year & "年" & dt.Month &"月_" & dt.Day
        
Dim idx As Integert2.cols(nm).Index
        
t2.LeftVisibleCol = idx
    
End If
End
 If

7、重新回到窗口设计器,将窗口的AfterLoad事件代码设置为:

Functions.Execute("BuildGanttTable")

8、选择窗口中的Table2控件,设置有关事件代码:

事件 代码
AfterScroll
Dim tbl As Table = Tables("任务")
If
e.Table.TopVisibleRow <> tbl.TopVisibleRow Then
    tbl.TopVisibleRow = e.
Table.TopVisibleRow
    e.
Table.TopVisibleRow = e.Table.TopVisibleRow '此行不可少,确保第一个可见行完整显示
End
If
DrawCell

If DrawGannt Then
    
Dim r As Row  = Tables("任务").Rows(e.Row.Index)
    
Dim dt1 As Date = r("开始日期")
    
Dim dt2 As Date = r("结束日期")
    
Dim dt As Date = e.Col.Name.Replace("年","-").Replace("月_","-")
    
If dt>=dt1 AndAlso dt<=dt2 Then
        
e.StartDraw()
        
If dt < Date.Today Then
            
e.Graphics.FillRectangle(Brushes.Green,e.x ,e.y + 5e.Widthe.Height - 10)
        
Else
            
e.Graphics.FillRectangle(Brushes.Red,e.x ,e.y + 3e.Widthe.Height - 7)
        
End If
        
e.EndDraw()
    
End If
End
 If

PositionChanged

 

Dim tbl As Table = Tables("任务")
If
 tbl.Position <> e.Table.Position Then
    
tbl.Position = e.Table.Position
End
 If

9、回到主界面,设置任务表的相关事件代码:

事件 代码
AfterScroll
If Forms("窗口1").Opened Then
   Dim
tbl As Table = Tables("窗口1_Table2")
  
If e.Table.TopVisibleRow <> tbl.TopVisibleRow Then
      tbl.TopVisibleRow = e.
Table.TopVisibleRow
      e.
Table.TopVisibleRow = e.Table.TopVisibleRow '此行不可少,确保第一个可见行完整显示
  
End If
   Functions.Execute(
"SetGanntLeftCol")
End
If
AfterSort

If Forms("窗口1").Opened()

    Tables("窗口1_Table2").Refresh() '刷新甘特图表

    Functions.Execute("SetGanntLeftCol")

End If

BeforeFilter

DrawGannt = False '暂停绘制甘特图

AfterFilter

If Forms("窗口1").Opened Then
     Functions.Execute("BuildGanttTable")

    Functions.Execute("AddGanttRows")

    Functions.Execute("SetGanntLeftCol")

End If

DrawGannt = True '回复绘制甘特图

If Forms("窗口1").Opened Then

    Tables("窗口1_Table2").Refresh() '刷新甘特图表

End If

PositionChanged

If Forms("窗口1").Opened() Then
    
Dim tbl As Table = Tables("窗口1_Table2")
    
If tbl.Position <> e.Table.Position Then
        
tbl.Position = e.Table.Position
    
End If
End
 If


本页地址:http://www.foxtable.com/webhelp/topics/2355.htm