The Exontrol's ExGantt component is our approach to create timeline charts (also known as Gantt charts). Gantt chart is a time-phased graphic display of activity durations. Activities are listed with other tabular information on the left side with time intervals over the bars. Activity durations are shown in the form of horizontal bars.
The main difference between eXGantt and eXG2antt is that eXGantt is a read
only control, so actually it is provided for viewing data only, while using the
eXG2antt users can edit/update at runtime the data ( cells, bars, and so on ). Also,
the eXG2antt component provides other features that the eXGantt does not
support such as: Built-in Editors, Summary Bars, Histogram, InsideZoom, Undo/Redo, Grouping
Bars, Summary Bars, PDM (Precedence Diagramming Method), Notes/Boxes and more.
Shortly, the eXGantt control is a limited version of the eXG2antt
component, while the eXG2antt is a full featured control. We provided 2
versions of our gantt view as that are application where only viewing
data is required so no user interaction and also there are applications
where changing data at runtime using UI is required.
In conclusion, the eX(G)rid-eX(G)antt, shortly eXG2antt,
combines the eXGrid and
eXGantt components in
a standalone component, or the eXGantt is a subset of eXG2antt
control.
By default, the exgantt setup installs the exprint.dll in your system
folder. If you can't locate there, please feel from to download it from
our web site. The Exontrol's ExPrint component ( exprint.dll ) provides
Print and Print Preview capabilities for the exGantt component, as well
for other components too. Once that you can have the exPrint component
in your Components list, insert a new instance of "ExPrint 1.0
Control Library" to your form and add the following VB code:
Private Sub Command1_Click()
With Print1
Set .PrintExt = Gantt1.Object
.Preview
End With
End Sub
The following sample shows how to call Preview method in C#:
The Exontrol's ExPrint component provides print
and print preview capabilities for the component. The Options
property of the ExPrint object may be used to pass custom options for
the print and print preview of the component.
Currently, the component supports the following options:
DateStart, indicates the new starting date for the print
and print preview. If missing, the default starting date is
used.
DateEnd, indicates the new ending date for the print and
print preview. If missing, the default ending date is used.
ColumnsOnEveryPage=#value#, specifies that the control
prints the columns section on each page, if the value is not zero.
If the ColumnsOnEveryPage option is negative, its absolute value
minus one, indicates the index of the column being printed on each
page, else if positive, it indicates the maximum ratio of page's
width that can be covered by the columns section on every page as
the following samples:
ColumnsOnEveryPage=0.5, specifies whether the control
prints the columns section on each page, and the area being used
by the columns section is not larger than half of the page.
ColumnsOnEveryPage=-1, specifies whether the control
prints the column ( with the index 0 ) section on each page.
FitToPage = On, specifies that the control's content to be
previewed / printed to a single page ( Fit-To-Page option ). The FitToPage option could be one of the following:
On, (Fit-To-Page) the control's content is printed to a single page ( version 6.1 )
p%, (Adjust-To) where p is a positive number that indicates the percent from normal size to adjust to. For instance, the "FitToPage = 50%" adjusts the control's content to 50% from normal size. ( version
8.0 )
w x, (Fit-To Wide) where w is a positive number that indicates that the control's content fits w pages wide by how many pages tall are required. For instance, "FitToPage = 3 x" fits the control's content to 3 pages wide by how many pages tall is are required. ( version
8.0 )
x t, (Fit-To Tall) where t is a positive number that specifies that the control's content fits t pages tall by how many pages wide are required. For instance, "FitToPage = x 2" fits the control's content to 2 pages tall by how many pages wide are required. ( version
8.0 )
w x t, (Fit-To) where w and t are positive numbers that specifies that the control's content fits w pages wide by t pages tall. For instance, "FitToPage = 3 x 2" fits the control's content to 3 pages wide by 2 pages tall. ( version
8.0 )
Print = Selection, prints only the selected items (
including the associated bars ). If the option is missing, the
entire chart is printing.
For instance, the following VB sample specifies the new dates for the
chart:
With Print1
' Use the DateStart and DateEnd options to specify the new range for printing the chart
.Options = "DateStart = Oct 17 2005; DateEnd = 12/1/2005"
Set .PrintExt = Gantt1.Object
.Preview
End With
The options are separated by ';' character or newline sequence (
"\r\n" or vbCrLf, ... ), and specifies the name of the option,
the '=' character and value of the option, like: "DateStart = Oct 17 2005; DateEnd = 12/1/2005"
Another option to print an user selected area is is to right click
the document in print preview, and define the new selected area by
moving the mouse while the right button is clicked. The user selected
area is painted in blue. This way you can print on the paper only the
blue section in the preview document.
You need to add a handler for DblClick
event. Next, use the BarFromPoint
property to determine the key of the bar from the cursor.
The following VB sample displays a message box when user double clicks a
bar:
Private Sub Gantt1_DblClick(Shift As Integer, X As Single, Y As Single)
With Gantt1.Chart
Dim k As Variant
k = .BarFromPoint(-1, -1)
MsgBox k
End With
End Sub
The following VFP sample displays a message box when user double clicks a
bar:
*** ActiveX Control Event ***
LPARAMETERS shift, x, y
with thisform.Gantt1.Chart
local k
k = .BarFromPoint(-1,-1)
MessageBox(k)
endwith
You can use the Zoom method.
Use the Level
property to access any level in the control's header. Each level has a Level object, where you can change the following properties:
Label,
Unit and
Count.
Please check also the UnitWidth property, that indicates the width
in pixels of the minimal level.
The RemoveAllItems
method removes all items. The bars and links related to an item, are
removed when an item is removed. Use the Clear
method to clear the columns collection. The RemoveAllItems method is
called automatically when the Clear method is called.
The ItemBar
property accesses properties for a specified bar. The ItemBar(exBarStart)
property indicates the time where the bar begins. The ItemBar(exBarEnd)
property indicates the time where the bar ends.
Open the control's help file ( click the Start button, click the Run
item, and type exgantt.chm, and press enter ), and locate the ItemBar
property in the Items collection. Click the ItemBarPropertyEnum
type of the Property parameter. There you will find a table with all
supported properties. The first column indicates the name of the
constant, the second column indicates the value of the constant, and the
last column describes what the property does.
Please check the Items.ItemBar(,,
exBarHAlignCaption ) property. The exBarHAlignCaption option aligns the
caption in the bar. Use the AddBar
property to assigns a caption to a bar.
Please check the Chart.DateFromPoint
and Chart.BarFromPoint
property. The DateFromPoint property determines the date from point. The
BarFromPoint property determines the key of the bar from the point. Use
the Items.ItemBar
property to access the bar inside the item. The ItemFromPoint
property retrieves the handle of the item from the point.
The Bars.AddShapeCorner
property defines a new bar based on an icon. Use the Images
method or ReplaceIcon
property to add new icons to the control's images collection.
Use the Items.ExpandItem
property to expand an item.
The following VB sample expands all items:
With Gantt1
.BeginUpdate
With .Items
For Each h In Gantt1.Items
.ExpandItem(h) = True
Next
End With
.EndUpdate
End With
The following VFP sample expands all items:
with thisform.Gantt1
.BeginUpdate
with .Items
for each h in thisform.Gantt1.Items
.DefaultItem = h
.ExpandItem(0) = .t.
next
endwith
.EndUpdate
endwith
The CellFont
property specifies the font being used in the cell. The ItemFont
property specifies the item's font. If any of this properties are not
set, the control's Font
specifies the cell's font. Use the ItemHeight
property to change the item's height.
The control supports filtering items using AND, OR, NOT
operators between columns. The FilterCriteria
property specifies the filter criteria. In your case, if you
have three columns, the control's FilterCriteria property
should be "%0 or %1 or %2". The "not
%1" specifies that the second column ( column's index
is 1 ) excludes the values selected in the drop down filter
window.
The Chart.BarFromPoint
property determine the key of the bar from point. The ItemFromPoint
property determines the item from point.
The following VB sample displays the start data of the
bar from the point:
Private Sub Gantt1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
With Gantt1
Dim h As HITEM, c As Long, hit As HitTestInfoEnum
h = .ItemFromPoint(-1, -1, c, hit)
If Not (h = 0) Then
Dim k As Variant
k = .Chart.BarFromPoint(-1, -1)
If Not IsEmpty(k) Then
Debug.Print .Items.ItemBar(h, k, exBarStart)
End If
End If
End With
End Sub
The following C++ sample displays the start data of the
bar from the point:
#include "Items.h"
#include "Chart.h"
CString V2Date( VARIANT* pvtValue )
{
COleVariant vtDate;
vtDate.ChangeType( VT_BSTR, pvtValue );
return V_BSTR( &vtDate );
}
void OnMouseDownGantt1(short Button, short Shift, long X, long Y)
{
long c = 0, hit = 0, h = m_gantt.GetItemFromPoint( -1, -1, &c, &hit );
if ( h != 0 )
{
COleVariant vtKey = m_gantt.GetChart().GetBarFromPoint( -1, -1 );
if ( V_VT( &vtKey ) != VT_EMPTY )
{
COleVariant vtStart = m_gantt.GetItems().GetItemBar( h, vtKey, 1 /*exBarStart*/ );
OutputDebugString( V2Date( &vtStart ) );
}
}
}
The following VB.NET sample displays the start data of
the bar from the point:
Private Sub AxGantt1_MouseDownEvent(ByVal sender As Object, ByVal e As AxEXGANTTLib._IGanttEvents_MouseDownEvent) Handles AxGantt1.MouseDownEvent
With AxGantt1
Dim c As Long, hit As EXGANTTLib.HitTestInfoEnum, h As Integer = .get_ItemFromPoint(-1, -1, c, hit)
If Not (h = 0) Then
Dim k As Object
k = .Chart.BarFromPoint(-1, -1)
If Not k Is Nothing Then
System.Diagnostics.Debug.WriteLine(.Items.ItemBar(h, k, EXGANTTLib.ItemBarPropertyEnum.exBarStart))
End If
End If
End With
End Sub
The following C# sample displays the start data of the
bar from the point:
private void axGantt1_MouseDownEvent(object sender, AxEXGANTTLib._IGanttEvents_MouseDownEvent e)
{
int c = 0;
EXGANTTLib.HitTestInfoEnum hit = EXGANTTLib.HitTestInfoEnum.exHTCell;
int h = axGantt1.get_ItemFromPoint(-1, -1, out c, out hit);
if (h != 0)
{
object k = axGantt1.Chart.get_BarFromPoint(-1, -1);
if (k != null)
System.Diagnostics.Debug.WriteLine( axGantt1.Items.get_ItemBar( h, k, EXGANTTLib.ItemBarPropertyEnum.exBarStart ) );
}
}
The following VFP sample displays the start data of the
bar from the point:
*** ActiveX Control Event ***
LPARAMETERS button, shift, x, y
With thisform.Gantt1
local h, c, hit
h = .ItemFromPoint(-1, -1, c, hit)
If (h # 0) Then
local k
k = .Chart.BarFromPoint(-1, -1)
If !Empty(k) Then
? .Items.ItemBar(h, k, 1)
EndIf
EndIf
EndWith
Please set the Chart.DrawDateTicker
property on False. The DrawDateTicker property retrieves or sets a value
that indicates whether the control draws a ticker around the current
date while cursor hovers the chart's client area.
LOCAL h
SCAN
_key="K_"+ALLTRIM(STR(projekte.ID))
WITH THISFORM.myplan.Items
h = .AddItem(ALLTRIM(projekte.project_name))
.AddBar( h,"Project Summary" , DTOT(projekte.sdate),DTOT(projekte.edate), _key, "" )
.ItemBar( h ,_key,3 ) = "my text"
ENDWITH
ENDSCAN
The h variable indicates the handle of the newly created item. This
value is always greater than 65000, so the VFP environment always fires
an error when compiling the AddBar and ItemBar properties because it
considers accessing an array, and its limit is 65000. Of course this
problem is related to VFP ignoring the fact that it is calling a
property! not an array, so our products provide a DefaultItem property
that help VFP users to pass this error. So, in VFP the above code should
look like follows:
The difference ( marked in red ) is that the first parameter for
properties like AddBar and ItemBar is 0, and before calling them the
Items.DefaultItem property indicates the handle of the item being
accessed. How it works? The control uses the value of the
Items.DefaultItem property, when the first parameter of the ItemBar,
AddBar and so on is 0. The AddItem property saves before the handle of
the newly created item to the DefaultItem property, and so the VFP error
is gone, and the code works like you expect.
The ScrollRange property does the trick. In previous versions, you can
simulate if you want to scroll the date between Jan 1, 2005 up to
Dec 31, 2006. It seems that the chart can scroll an endless date and I
only want to limit to scroll the chart date from Jan 1, 2005 to Dec 31,
2006. The control fires the DateChange
event when the user scrolls the chart's area, or if the FirstVisibleDate
property is changed.
The following VB sample limits the scrolling area to Dec 31, 2006,
from Jan 1, 2005.
Private Function LastVisibleDate(ByVal g As EXGANTTLibCtl.Gantt) As Date
With Gantt1
With .Chart
Dim d As Date
d = .FirstVisibleDate
Do While .IsDateVisible(d)
d = .NextDate(d, exDay, 1)
Loop
End With
End With
LastVisibleDate = d - 1
End Function
Private Sub Gantt1_DateChange()
Dim dMin As Date, dMax As Date
dMin = "1/1/2005"
dMax = "31/12/2006"
With Gantt1.Chart
If .FirstVisibleDate < dMin Then
.FirstVisibleDate = dMin
End If
If LastVisibleDate(Gantt1) > dMax Then
.FirstVisibleDate = dMax - (LastVisibleDate(Gantt1) - .FirstVisibleDate) + 1
End If
End With
End Sub
The ItemBar(exBarStart)
and ItemBar(exBarEnd) properties specify the starting and ending
date of the bar. A bar is determined by the starting and ending date.
The following C++ function determines whether two bars are
intersected:
BOOL Intersection( DATE aStart, DATE aEnd, DATE bStart, DATE bEnd )
{
DATE am = MIN( aStart, aEnd ), aM = MAX( aStart, aEnd );
DATE bm = MIN( bStart, bEnd ), bM = MAX( bStart, bEnd );
if ( bM < am )
return FALSE;
if ( bm > aM )
return FALSE;
return TRUE;
}
where the MIN and MAX functions determines the minimum and maximum
values like follows:
DATE MIN( DATE a, DATE b )
{
if ( a < b )
return a;
return b;
}
DATE MAX( DATE a, DATE b )
{
if ( a > b )
return a;
return b;
}
In VB the functions looks like follows:
Private Function Intersect(ByVal aStart As Date, ByVal aEnd As Date, ByVal bStart As Date, ByVal bEnd As Date) As Boolean
Dim aMin As Date, aMax As Date
aMin = MIN(aStart, aEnd)
aMax = MAX(aStart, aEnd)
Dim bMin As Date, bMax As Date
bMin = MIN(bStart, bEnd)
bMax = MAX(bStart, bEnd)
If (bMax < aMin) Then
Intersect = False
Exit Function
End If
If (bMin > aMax) Then
Intersect = False
Exit Function
End If
Intersect = True
End Function
where the MIN and MAX functions looks like:
Private Function MIN(ByVal a As Date, ByVal b As Date) As Date
If (a < b) Then
MIN = a
Exit Function
End If
MIN = b
End Function
Private Function MAX(ByVal a As Date, ByVal b As Date) As Date
If (a > b) Then
MAX = a
Exit Function
End If
MAX = b
End Function
By default, the control doesn't select the item being expanded or
collapsed, when the user clicks the +/- buttons. Thought you can have
the item selected, by handling the AfterExpandItem
event like in the following sample:
Private Sub Gantt1_AfterExpandItem(ByVal Item As EXGANTTLibCtl.HITEM)
Gantt1.Items.SelectItem(Item) = True
End Sub
Use the SelectItem property to select or unselect a specified item.
The control provides the Copy
method that saves the control's content to clipboard, in Enhanced Metafile
(EMF) format. The Enhanced Metafile format is a 32-bit format that can contain both vector information and bitmap information. This format is an improvement over the Windows Metafile Format and contains extended features, such as the following:
Built-in scaling information
Built-in descriptions that are saved with the file
Improvements in color palettes and device independence
The EMF format is an extensible format, which means that a programmer can modify the original specification to add functionality or to meet specific needs. You can paste this
format to Microsoft
Word, Excel, Front Page, Microsoft Image Composer and any application that know to handle
EMF formats.
The LevelCount
property specifies the number of levels being displayed.
The Level
property retrieves the level object to access the Label
the and Unit
properties that specifies the label being displayed in the level, and
the unit being displayed. The Count
property specifies the number of units displays at once. The FirstVisibleDate
property specifies the first date/time being visible in the chart's
area.
1
The first level displays each month in the year, the
next level displays the week numbers.
The first level displays the month, the year and the number of the
week in the year , the second level displays the name of the week day,
and the third level displays the day of the month. Here's the template:
The following VB sample displays your header using 3 levels as shown
above:
With Gantt1
.BeginUpdate
With .Chart
.LevelCount = 3
With .Level(0)
.Label = "<b><%mmm%>, <%yyyy%></b> <r>Week: <%ww%>"
.Unit = EXGANTTLibCtl.UnitEnum.exWeek
End With
.Level(1).Label = "<%d1%>"
.Level(2).Label = "<%d%>"
End With
.EndUpdate
End With
The following VFP sample displays your header using 3 levels:
with thisform.gantt1
.BeginUpdate()
with .Chart
.LevelCount = 3
with .Level(0)
.Label = "<b><%mmm%>, <%yyyy%></b> <r>Week: <%ww%>"
.Unit = 256
endwith
.Level(1).Label = "<%d1%>"
.Level(2).Label = "<%d%>"
endwith
.EndUpdate()
endwith
The following VB.NET sample displays your header using 3
levels:
With AxGantt1
.BeginUpdate()
With .Chart
.LevelCount = 3
With .Level(0)
.Label = "<b><%mmm%>, <%yyyy%></b> <r>Week: <%ww%>"
.Unit = EXGANTTLib.UnitEnum.exWeek
End With
.Level(1).Label = "<%d1%>"
.Level(2).Label = "<%d%>"
End With
.EndUpdate()
End With
The following C# sample displays your header using 3 levels:
The control provides the SaveXML
method that saves the control's data to XML document. Use the LoadXML
method to load XML documents saved using the SaveXML method. The SaveXML
method may save data to a file , an XML document object, or a custom
object that supports persistence like described here:
String - Specifies the file name. Note that this must be a file
name, rather than a URL. The file is created if necessary and the
contents are entirely replaced with the contents of the saved
document. For example:
Gantt1.SaveXML("sample.xml")
XML Document Object. For example:
Dim xmldoc as Object
Set xmldoc = CreateObject("MSXML.DOMDocument")
Gantt1.SaveXML(xmldoc)
Custom object supporting persistence - Any other
custom COM object that supports QueryInterface for IStream,
IPersistStream, or IPersistStreamInit can also be
provided here and the document will be saved accordingly. In the IStream
case, the IStream::Write method will be called as it saves
the document; in the IPersistStream case, IPersistStream::Load
will be called with an IStream that supports the Read,
Seek, and Stat methods.
The Color
property of the Bar object specifies the color being used to paint the
bar. This property changes the colors for all bars with the same name.
For instance, if you have 3 "Task" bars, and you are changing
the color for the "Task" bar, the color is applied to all
"Task" bars in the chart. For instance, in order to provide
"Task" bars with different colors, you can use the Copy
method to copy the Task bar to a new bar, and use the Color to change
the color of the bar. The following function generates a Task bar with
specified color:
Private Function AddTask(ByVal gantt As EXGANTTLibCtl.Gantt, ByVal clr As Long) As String
Dim sT As String
sT = "Task:" & clr
With gantt.Chart.Bars.Copy("Task", sT)
.color = clr
End With
AddTask = sT
End Function
The function generates a new bar with the name "Task:color",
where the color is the color being used, and retrieves the name of the
new bar being added. The Copy method retrieves the bar being found with
specified name, or creates a new bar if the name is not found in the
Bars collection, so AddTask function gets you the name of the bar you
should use to specify the color for the bar being added as in the
following sample:
With Gantt1.Items
Dim d As Date
d = Gantt1.Chart.FirstVisibleDate
.AddBar .FirstVisibleItem, AddTask(Gantt1, vbRed), d, d + 4, "Red"
End With
The MarkSelectDateColor
property specifies the color being used to mark the selected dates. If
the MarkSelectDateColor property is the same as the BackColor
property of the Chart
object, the selected dates are not shown.
The NonworkingHours
property specifies the non-working hours in a day. The non-working hours
are shown, if your chart displays hours or groups of hours in a day. The
NonworkingDays
property specifies the non-working days in a week. The non-working days
are shown if the chart displays days or group of days.
The ScrollOrderParts
does the trick. The left and right buttons are displayed together if you
call ScrollOrderParts = "l,r". Using the ScrollOrderParts
property you can customize the position of the buttons in the control's
scroll bars.
The CustomFilter
property of the Column object. specifies the list of custom filters that
appear in the drop down filter window. For instance, if the CustomFilter
= "Excel Spreadsheets (*.xls )||*.xls|||Word Documents||*.doc|||Powerpoint
Presentations||*.pps|||Text Documents (*.log,*.txt)||*.txt|*.log"
the drop down filter window shows the following pre-defined
filters:
Excel Spreadsheets (*.xls )
Word Documents
Powerpoint Presentations
Text Documents (*.log,*.txt)
So, if the user selects the Word Documents, the control filters the
column for cells that matches the "*.doc" pattern.
The Link(exLinkText)
property specifies the HTML text being displayed on the link. The AddLink
method adds a link between two bars. The HTMLPicture
property adds a picture that can be used in HTML strings, using the <img>
tag. For instance the following code Gantt1.Items.Link("Link", exLinkText) = " <img>excel</img><br><br><b>doc.xls"
assigns a text to the link, and it shows like follows:
If the HTMLPicture property doesn't include any excel
identifier, the image on the link is not displayed, so the <img>
tag is ignored.
The HitTestInfoEnum.exHTBetween
value indicates whether the cursor is between two items. For instance, you can
provide a visual effect for the item while performing OLE drag and drop
operations, when the cursor is in the top half of the item, using the exDragDropListTop,
or in the second half using the exDragDropListBottom value. In the same way you
can provide a visual effect when the cursor is over or between two items, using
the exDragDropListOver and exDragDropListBetween values. The ItemFromPoint
property retrieves the handle of the item from the cursor, and retrieves also a
code (HitTestInfo parameter), to indicate the part in the item where the cursor
is. So, the exHTBetween value indicates whether the cursor is between items. The
exHTBetween is an OR combination with other predefined values, so you must call HitTestInfo
AND 0x1000 to check if the cursor is between rows/items as in the following
samples:
The following VB sample displays a message when the cursor is between two
items:
Private Sub Gantt1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim i As HITEM, c As Long, h As HitTestInfoEnum
i = Gantt1.ItemFromPoint(-1, -1, c, h)
If Not (i = 0) Then
If (h And exHTBetween) Then
Debug.Print "The cursor is between two items."
Else
Debug.Print "The cursor is over the item."
End If
End If
End Sub
The following VB.NET sample displays a message when the cursor is between two
items:
Private Sub AxGantt1_MouseMoveEvent(ByVal sender As System.Object, ByVal e As AxEXGANTTLib._IGanttEvents_MouseMoveEvent) Handles AxGantt1.MouseMoveEvent
With AxGantt1
Dim c As Integer, h As EXGANTTLib.HitTestInfoEnum
Dim i As Integer = .get_ItemFromPoint(-1, -1, c, h)
If Not i = 0 Then
If (h And EXGANTTLib.HitTestInfoEnum.exHTBetween) Then
Debug.Print("The cursor is between items.")
Else
Debug.Print("The cursor is over the item.")
End If
End If
End With
End Sub
The following C# sample displays a message when the cursor is between two
items:
private void axGantt1_MouseMoveEvent(object sender, AxEXGANTTLib._IGanttEvents_MouseMoveEvent e)
{
int c = 0;
EXGANTTLib.HitTestInfoEnum h;
int i = axGantt1.get_ItemFromPoint(-1, -1, out c, out h);
if (i != 0)
if ( (h & EXGANTTLib.HitTestInfoEnum.exHTBetween) == EXGANTTLib.HitTestInfoEnum.exHTBetween )
System.Diagnostics.Debug.Print("The cursor is between items.");
else
System.Diagnostics.Debug.Print("The cursor is over the item.");
}
The following C++ sample displays a message when the cursor is between two
items:
void OnMouseMoveGantt1(short Button, short Shift, long X, long Y)
{
long c = 0, h = 0;
long i = m_tree.GetItemFromPoint( -1, -1, &c, &h );
if ( i != 0 )
if ( h & 0x1000 /*exHTBetween*/ )
OutputDebugString( "The cursor is between items.\n" );
else
OutputDebugString( "The cursor is over the item.\n" );
}
The following VFP sample displays a message when the cursor is between two
items:
*** ActiveX Control Event ***
LPARAMETERS button, shift, x, y
local c, hit
c = 0
hit = 0
with thisform.Gantt1
.Items.DefaultItem = .ItemFromPoint( x, y, @c, @hit )
if ( .Items.DefaultItem <> 0 )
if bitand(hit,0x1000) = 0x1000
wait window nowait "The cursor is between items."
else
wait window nowait "The cursor is over the item."
endif
endif
endwith
Use the PaneWidth
property to change the width of the left or right panel in the Gantt control.
The following VB sample resizes the chart area as soon as the Gantt control
is resized:
Private Sub Form_Resize()
On Error Resume Next
With Gantt1
.BeginUpdate
.Width = ScaleWidth - 2 * .Left
.Height = ScaleHeight - 2 * .Top
.Chart.PaneWidth(True) = .Width / Screen.TwipsPerPixelX / 2
.EndUpdate
End With
End Sub
The following VFP sample resizes the chart area as soon as the Gantt control
is resized:
The following VB.NET sample resizes the chart area as soon as the Gantt
control is resized:
Private Sub AxGantt1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles AxGantt1.Resize
With AxGantt1
If (.IsHandleCreated) Then
.Chart.PaneWidth(True) = .Width / 2
End If
End With
End Sub
The following C# sample resizes the chart area as soon as the Gantt control
is resized:
Definitely it doesn't get printed to a single page. It prints on how many pages
are required. If a simple page is required then the chart is printed to a single
page, else it is printed on multiple pages.
There are several options in order to display a different content for the
column. By default, the Items.CellCaption property indicates the value being shown
in the cell.
Column.FormatColumn property specifies a formula to display the column's
new content, using predefined functions for numbers, strings, dates and so
on.
Change the Value parameter of the FormatColumn event which is fired if the
Column.FireFormatColumn property is True. For instance the following sample
displays the second column using current currency format with 2
decimals. The Item parameter of the FormatColumn event indicates the item
where the cell is hosted, the ColIndex indicates the column where the cell
belongs, while the Value parameter indicates the cell's value before
formatting and after. In case you need formatting multiple columns, you
can distingue them using the ColIndex parameter.
Private Sub Form_Load()
With Gantt1
.BeginUpdate
.Columns.Add "A"
.Columns.Add("B").FireFormatColumn = True ' Index of it is 1
With .Items
.AddItem Array("One", 1)
.AddItem Array("Two", 2)
End With
.EndUpdate
End With
End Sub
Private Sub Gantt1_FormatColumn(ByVal Item As EXGANTTLibCtl.HITEM, ByVal ColIndex As Long, Value As Variant)
Value = FormatCurrency(Value, 2, vbUseDefault)
End Sub
The OLEDropMode
property of the control must be set on exOLEDropManual (1). If this property is
set, the control fires the OLEDragDrop
event which notifies that the user drags data to the control. The Files
collection holds a collection of files being dragged.
The following VB sample copies the original icon being displayed in
Windows Explorer and displays it on the control:
Private Declare Function SHGetFileInfo Lib "shell32.dll" Alias "SHGetFileInfoA" (ByVal pszPath As String, ByVal dwFileAttributes As Long, psfi As SHFILEINFO, ByVal cbFileInfo As Long, ByVal uFlags As Long) As Long
Private Const SHGFI_OPENICON = &H2 ' get open icon
Private Const SHGFI_SMALLICON = &H1 ' get small icon
Private Const SHGFI_SYSICONINDEX = &H4000
Private Const SHGFI_ICON = &H100 ' get icon
Private Const MAX_PATH = 260
Private Type SHFILEINFO
hIcon As Long ' out: icon
iIcon As Long ' out: icon index
dwAttributes As Long ' out: SFGAO_ flags
szDisplayName As String * MAX_PATH ' out: display name (or path)
szTypeName As String * 80 ' out: type name
End Type
Private iIcon As Long
Private Sub Form_Load()
iIcon = 1
With Gantt1
.BeginUpdate
.OLEDropMode = exOLEDropManual
.FullRowSelect = False
.DefaultItemHeight = 18
.Columns.Add "Icons"
.EndUpdate
End With
End Sub
Private Sub Gantt1_OLEDragDrop(ByVal Data As EXGANTTLibCtl.IExDataObject, Effect As Long, ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
With Data.Files
If (.Count > 0) Then
For i = 0 To .Count - 1
With Gantt1
Dim g As SHFILEINFO
.BeginUpdate
SHGetFileInfo Data.Files.Item(i), 0, g, Len(g), SHGFI_ICON Or SHGFI_SMALLICON
.ReplaceIcon g.hIcon
.Items.CellImage(Gantt1.Items.AddItem(Data.Files.Item(i)), 0) = iIcon
iIcon = iIcon + 1
.EndUpdate
End With
Next
End If
End With
End Sub
Private Sub Gantt1_OLEDragOver(ByVal Data As EXGANTTLibCtl.IExDataObject, Effect As Long, ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single, ByVal State As Integer)
If (Data.Files.Count = 0) Then
Effect = 0
End If
End Sub
The sample uses the SHGetFileInfo API function to retrieve the handle of the
icon ( HICON ) to be copied and displayed in the control.
If you want to limit just a margin of the chart, you can handle the DateChange
event to specify the correct value for the FirstVisibleDate property of the
Chart object like in the following sample:
Private Function Max(a, b)
If (a < b) Then
Max = b
Else
Max = a
End If
End Function
Private Sub Gantt1_DateChange()
With Gantt1
Dim dLimit As Date
dLimit = #1/1/2010#
.Chart.FirstVisibleDate = Max(dLimit, .Chart.FirstVisibleDate)
.ScrollPartEnable(exHChartScroll, exLeftBPart) = .Chart.FirstVisibleDate > dLimit
End With
End Sub
The sample limits the FirstVisibleDate property of the chart so it won't be
less than January 1st of 2010, and disables the left scroll button in the chart
if FirstVisibleDate property is at limit.
The most probably the problem is that on one machine the date-time are read
correctly, while on the other is not, and this is happen due different settings
for Date-Time in the control panel. We would suggest checking the following:
check the type for DateStart and DateEnd parameters of the AddBar method.
If this is not of DateTime type, make sure that the values being used are
correctly formatted on the machine with the problem. For instance, the
string "1/2/2001" on a machine with English DateTime set indicates
the January the 2nd, while on a German machine, it means February the 1st.
check the Regional and Language options on your machine and the other
machine. This way you can see the difference.
Suggestion: Use the DateTime type ( or equivalent for your developing
language ) for DateStart/DateEnd parameters of the AddBar method of Items
objects.
Here is 2 options to remove the selected items in the control:
Collects the items to be removed, using the Items.SelectCount and
Items.SelectedItem properties. Once the collection is completed, you can
call the Items.RemoveItem for each element being found.
While the Items.SelectCount property is greater than 0, call the
Items.RemoveItem( Items.SelectedItem(0) ), so removes the first selected
item until all all released.
The following VB sample shows the method 1:
Private Sub removeSelection1()
Dim i As Long, h As Variant
Dim cItems As New Collection
Gantt1.BeginUpdate
With Gantt1.Items
For i = 0 To .SelectCount - 1
cItems.Add .SelectedItem(i)
Next
For Each h In cItems
.RemoveItem h
Next
End With
Gantt1.EndUpdate
End Sub
The following VB sample shows the method 2:
Private Sub removeSelection2()
Gantt1.BeginUpdate
With Gantt1.Items
While .SelectCount > 0
.RemoveItem .SelectedItem(0)
Wend
End With
Gantt1.EndUpdate
End Sub
You should call the DoEvents method before calling the EnsureVisibleItem method.
For /NET you should use the Application.DoEvents method. For Delphi, you should
use the Application.ProcessMessages.
There are the several ways of enumerating the
items/cells in the control. The following samples
are in VB, but they can be easily converted to any other
programming language. This samples shows you an idea how
easily you can enumerate through the items.
A). Using the GetItems method of the control. The
GetItems method gets the items as they are displayed,
sorted and filtered to an array or vector. Also, the GetItems method collect
the child items as well, no matter if the parent item is
collapsed. The GetItems method returns an array. For
instance, if your control contains 1 column, the
GetItems will retrieves a one-dimensional
array. A 2 columns will get a two-dimensional
array, an so on. You can use the PutItems method to
insert the array to the control.
B). Using the for each statement for Items
property of the control. The Items property gets a
collection of items as they were added. This method lists
the items by index not by their positions. The items is represented
by handles, so the handle can be used in the Cell properties
to refer the cell. For instance,
Items.CellCaption(Handle,Column) gets the cell from the Item
with the specified handle on specified column. The following
sample displays the cells in the first column as they were
added:
With Gantt1
Dim h As Variant
For Each h In .Items
Debug.Print .Items.CellCaption(h, 0)
Next
End With
If you need to access multiple columns add the Debug.Print
.Items.CellCaption(h, 1), Debug.Print .Items.CellCaption(h,
2) ... for each column you require.
C). A similar approach to B is using the
Items.ItemCount and Items.ItemByIndex properties. This method
lists the items by index not by their positions.
With Gantt1
Dim i As Long
With .Items
For i = 0 To .ItemCount - 1
Debug.Print .CellCaption(.ItemByIndex(i), 0)
Next
End With
End With
The Items. ItemByIndex retrieves the handle of the item
giving its index. For instance, the first added item has the
index 0, the second added item has the index 1, and so on.
D). Using the Items.NextVisibleItem property. This
method gets the items as they are displayed, sorted and
filtered.
With Gantt1
With .Items
Dim h As Long
h = .RootItem(0)
While Not h = 0
Debug.Print .CellCaption(h, 0)
h = .NextVisibleItem(h)
Wend
End With
End With
E). Using the Items.ItemChild and
Items.NextSiblingItem property. This method enumerates recursively
the items and its children. This
method gets the items as they are displayed, sorted and
filtered, including the children items that are not visible
aka parent item is collapsed.
With Gantt1
With .Items
For i = 0 To .RootCount - 1
RecItem Gantt1, .RootItem(i)
Next
End With
End With
Sub RecItem(ByVal c As Object, ByVal h As Long)
If Not(h = 0) Then
Dim hChild As Long
With c.Items
Debug.Print .CellCaption(h, 0)
hChild = .ItemChild(h)
While Not (hChild = 0)
RecItem c, hChild
hChild = .NextSiblingItem(hChild)
Wend
End With
End If
End Sub
The SingleSel property specifies whether the control supports single or multiple
selected items. If the SingleSel property is True ( by default ), the user can
select a single item/row only. The Items.FocusItem property indicates the handle
of the item that has the focus. The
control fires the SelectionChanged event when the control's selection is
changed. The
SelectCount property specifies the count of selected items/rows. If the
SingleSel property is True, the SelectCount property can be 0 or 1.
The following code displays the selected values:
Private Sub enumSelection(ByVal g As Object)
With g.Items
For i = 1 To .SelectCount
Debug.Print .CellCaption(.SelectedItem(i - 1), 0)
Next
End With
End Sub
Private Sub Gantt1_SelectionChanged()
enumSelection Gantt1
End Sub
As the control supports multiple columns, the following code displays the
selected values for all columns:
Private Sub enumSelection(ByVal g As Object)
With g.Items
Dim nColumns As Long
nColumns = g.Columns.Count
For i = 1 To .SelectCount
Dim h As HITEM
h = .SelectedItem(i - 1)
For j = 1 To nColumns
Debug.Print .CellCaption(h, j - 1)
Next
Next
End With
End Sub
Private Sub Gantt1_SelectionChanged()
enumSelection Gantt1
End Sub
Here's some ideas on how you can use arrays with the
control.
A). Using the GetItems/PutItems to get or put the
items/cells using arrays. The GetItems method gets the
items/cells of the control to a safe array. The PutItems
inserts the array of values to the control. For instance the
following sample adds 3 columns and 1001 items from an
array:
/COM version
With Gantt1
.Columns.Add "C1"
.Columns.Add "C2"
.Columns.Add "C3"
Dim v(2, 1000) As String
v(1, 10) = "zece"
.PutItems v
End With
In VB the arrays is zero-based, so 2 indicates actually
0, 1 and 2 ( 3 columns ).
/NET or /WPF version
With Exgantt1
.Columns.Add("C1")
.Columns.Add("C2")
.Columns.Add("C3")
Dim v(2, 1000) As String
v(1, 10) = "zece"
.PutItems(v)
End With
B1). You can use the PutItems method to insert a
hierarchy, for single-column control. The following sample
adds a hierarchy as Root\Child 1, Child 2\SubChild 1,
SubChild 2
/COM version
With Gantt1
.LinesAtRoot = exLinesAtRoot
.Columns.Add "Nodes"
.PutItems Array("Root", Array("Child 1", "Child 2", Array("SubChild 1", "SubChild 2")))
End With
/NET or /WPF version
With Exgantt1
.LinesAtRoot = exontrol.EXGANTTLib.LinesAtRootEnum.exLinesAtRoot
.Columns.Add("Nodes")
.PutItems(New Object() {"Root", New Object() {"Child 1", "Child 2", New Object() {"SubChild 1", "SubChild 2"}}})
End With
B2). You can use the PutItems method to insert a
hierarchy, for single-column control, as child items. The following sample
adds an item New, and a sub-hierarchy Root\Child 1, Child 2\SubChild 1,
SubChild 2
/COM version
With Gantt1
.LinesAtRoot = exLinesAtRoot
.Columns.Add "Nodes"
.PutItems Array("Root", Array("Child 1", "Child 2", Array("SubChild 1", "SubChild 2"))), .Items.AddItem("new")
End With
/NET or /WPF version
With Exgantt1
.LinesAtRoot = exontrol.EXGANTTLib.LinesAtRootEnum.exLinesAtRoot
.Columns.Add("Nodes")
.PutItems(New Object() {"Root", New Object() {"Child 1", "Child 2", New Object() {"SubChild 1", "SubChild 2"}}}, .Items.AddItem("new"))
End With
C). You can use the arrays to fill a
multiple-columns control in Items.AddItem/Items.InsertItem
methods as in the following sample:
/COM version
With Gantt1
.Columns.Add "C1"
.Columns.Add "C2"
.Columns.Add "C3"
With .Items
.AddItem Array("Cell 1.1", "Cell 1.2", "Cell 1.3")
.AddItem Array("Cell 2.1", "Cell 2.2", "Cell 2.3")
End With
End With
/NET or /WPF version
With Exgantt1
.Columns.Add("C1")
.Columns.Add("C2")
.Columns.Add("C3")
With .Items
.AddItem(New Object() {"Cell 1.1", "Cell 1.2", "Cell 1.3"})
.AddItem(New Object() {"Cell 2.1", "Cell 2.2", "Cell 2.3"})
End With
End With
The control provides the Print and Print Preview using the Exontrol's ExPrint
component. Please check
the printing FAQ for
adding Print and Print Preview support in your programming language.
In order to prevent updating the control during Print and PrintPreview you
need to call the BeginUpdate of the control during the Refreshing
event of the eXPrint, and call the EndUpdate once the Refresh
event of the eXPrint occurs, like in the following sample.
Private Sub Print1_Refreshing()
Gantt1.BeginUpdate
End Sub
Private Sub Print1_Refresh()
Gantt1.EndUpdate
End Sub
The ItemFromPoint(-1,-1) property gets the handle if the item, index of the
column and the hit-test position from the cursor position. Usually, the you
think that the ItemFromPoint(-1,-1) is not working in debug mode, because you
have set the breakpoint on the property itself, and you are moving the cursor
position by the time the ItemFromPoint property is called. What you can do, is
to set the break-point after calling the ItemFromPoint property is called, so
the correct position of the cursor is taken when the property is invoked. In
other words, please add the following code, and see that the handle of the item
being clicked is displayed correctly, like in the following VB sample:
Private Sub Gantt1_Click()
Dim c As Long, hit As EXGANTTLibCtl.HitTestInfoEnum
Debug.Print Gantt1.ItemFromPoint(-1, -1, c, hit)
End Sub
The BeforeExpandItem event is fired when an item is about to be expanded, by code or using the control's user interface ( such as
clicking the +/- expanding button ). Also, the BeforeExpandItem event may occur
for items with the ItemHasChildren property set on True, when the user clicks
the filter drop down button. This is by design, to include not-loaded items in
the drop down filter window. Usually, the BeforeExpandItem event is used to load
virtually a hierarchy, for instance, when the user clicks the +/- expanding
button.
The following methods, can be used to prevent firing the BeforeExpandItem event when
the user clicks the drop down filter button:
Use no ItemHasChildren property on True, in other words you
can load on init time, the entire hierarchy collection
Set the FilterList property of the Column object to exRootItems value (4), so no child items are collected in the drop down filter
list
Use a counter that's increased when MouseDown event occurs
and it is decreased when MouseUp event is fired. You can use the ColumnFromPoint property to check if the user clicks the headers.
During the BeforeExpandItem event you can prevent adding a sub-child if the
counter is not zero.
The control's ClearFilter method ( or clicking the X button in the filter bar )
does the following:
set the Column.Filter property on empty, IF the Column.FilterType property
is exNumeric, exCheck or exImage, else
set the Column.FilterType property on exAll. IF the Column.FilterOnType
property is True, the Column.Filter is set on empty too, else the
Column.Filter property remains.
The FilterType property of the Column object indicates the type of the filter
to be applied on the column. Generally, you can check for exAll on FiterType
unless you are not using the exNumeric, exCheck or exImage type of column's
filters.
The following VB function returns False, if no filter is applied, or True,
if any filter is applied. This sample works ok, if no using any of exNumeric,
exCheck or exImage types
Private Function hasFilter(ByVal g As Object) As Boolean
Dim c As Object
For Each c In g.Columns
If Not (c.FilterType = 0) Then
hasFilter = True
Exit Function
End If
Next
hasFilter = False
End Function
The following VB function returns False, if no filter is applied, or True,
if any filter is applied. This sample works for all type of filters:
Private Function hasFilter(ByVal g As Object) As Boolean
Dim c As Object
For Each c In g.Columns
Select Case c.FilterType
Case 5, 6, 10 ' exNumeric, exCheck, exImage
hasFilter = Not (c.Filter.Length = 0)
Case Else
hasFilter = Not (c.FilterType = 0) ' exAll
End Select
If (hasFilter) Then
Exit Function
End If
Next
hasFilter = False
End Function
Starting with the version 8.0, the control supports Fit-To-Page feature,
using the FitToPage = On option.
The FitToPage option could be one of the following:
On, (Fit-To-Page) the control's content is printed to a single
page ( version 8.0 )
p%, (Adjust-To) where p is a positive number that indicates the
percent from normal size to adjust to. For instance, the "FitToPage =
50%" adjusts the control's content to 50% from normal size. ( version
8.0 )
w x, (Fit-To Wide) where w is a positive number that indicates
that the control's content fits w pages wide by how many pages tall are
required. For instance, "FitToPage = 3 x" fits the control's
content to 3 pages wide by how many pages tall is are required. ( version
8.0 )
x t, (Fit-To Tall) where t is a positive number that specifies
that the control's content fits t pages tall by how many pages wide are
required. For instance, "FitToPage = x 2" fits the control's
content to 2 pages tall by how many pages wide are required. ( version 8.0
)
w x t, (Fit-To) where w and t are positive numbers that specifies
that the control's content fits w pages wide by t pages tall. For
instance, "FitToPage = 3 x 2" fits the control's content to 3
pages wide by 2 pages tall. ( version 8.0 )
The following VB sample changes the UnitWidth
property of the eXG2ant's Chart
object so, the entire chart is printed to a single page:
With Print1
Dim l As Long
With Gantt1.Chart
l = .UnitWidth
.UnitWidth = (Print1.ClientWidth - .PaneWidth(False)) / .CountVisibleUnits()
End With
Set .PrintExt = Gantt1.Object
.Preview
Gantt1.Chart.UnitWidth = l
End With
The equivalent sample in dBASE Plus is:
local oPrint,oGantt
oPrint = form.exprint.nativeObject
oGantt = form.Activex1.nativeObject
local l
l = oGantt.Chart.UnitWidth
oGantt.Chart.UnitWidth = (oPrint.ClientWidth() - oGantt.Chart.PaneWidth(.f.)) / oGantt.Chart.CountVisibleUnits()
oPrint.PrintExt = form.Activex1.nativeObject
oPrint.Preview()
oGantt.Chart.UnitWidth = l
The sample has the disadvantage that once the user changes the Page's setup
during Previewing the code is not re-executed, so the chart is displayed as it
is on the screen. In order to update the UnitWidth property once the page's
setup is changed, we need to handle the Refreshing and
Refresh events
of the eXPrint component as shown
in the following VB sample:
Dim nUnitWidth As Long
Private Sub Print1_Refreshing()
With Gantt1.Chart
nUnitWidth = .UnitWidth
.UnitWidth = (Print1.ClientWidth - .PaneWidth(False)) / .CountVisibleUnits()
End With
End Sub
Private Sub Print1_Refresh()
Gantt1.Chart.UnitWidth = nUnitWidth
End Sub
Private Sub Preview_Click()
With Print1
Set .PrintExt = Gantt1.Object
.Preview
End With
End Sub
The sample changes the UnitWidth property of the Chart
during the Refreshing event, so the chart fits to page, and restores the
UnitWidth's value when the Refresh event is invoked.
The following
VB/NET sample changes the UnitWidth property so the chart fits to page:
Dim nUnitWidth As Long
Private Sub Exprint1_RefreshingEvent(ByVal sender As System.Object) Handles Exprint1.RefreshingEvent
With ExGantt1.Chart
nUnitWidth = .UnitWidth
.UnitWidth = (Exprint1.ClientWidth - .get_PaneWidth(False)) / .CountVisibleUnits()
End With
End Sub
Private Sub Exprint1_RefreshEvent(ByVal sender As System.Object) Handles Exprint1.RefreshEvent
ExGantt1.Chart.UnitWidth = nUnitWidth
End Sub
Private Sub Preview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Preview.Click
Exprint1.PrintExt = ExGantt1
Exprint1.Preview()
End Sub
The Items.ItemByIndex(index) property gets the handle of the item/row giving its
index.
If you can not locate the ItemByIndex property in the Items collection you
should look for Items.get_ItemByIndex(index), Items[index]
or Items(index) instead.
The tooltip is automatically hidden when user moves the mouse or a key is
pressed. In case a message box or a form is shown, none of them is happen, so
the tooltip may still be shown. For that, you can call the PostMessage .hwnd,
512, 0, 0 before showing your message or dialog like in the following sample.
The hWnd indicates the handle of the control ( hWnd property ).
Private Sub Gantt1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
If (Button = 2) Then
With Gantt1
Dim i As Long, c As Long, hit As HitTestInfoEnum
i = .ItemFromPoint(-1, -1, c, hit)
If Not i = 0 Then
PostMessage .hwnd, &H200, 0, 0
MsgBox .Items.CellCaption(i, c)
End If
End With
End If
End Sub
The ScrollPos property changes the control's scroll position ( horizontal or
vertical scroll position ). The OffsetChanged event occurs when the control's
scroll horizontal or vertical position is changed, in other words all it is
required is calling the ScrollPos during the OffsetChanged like in the following
sample. Because the ScrollPos property invokes the OffsetChanged, you must use a
member flag ( iSyncing ) to prevent recursive calls:
Private iSyncing As Long
Private Sub Gantt1_OffsetChanged(ByVal Horizontal As Boolean, ByVal NewVal As Long)
If (iSyncing = 0) Then
iSyncing = iSyncing + 1
Gantt2.ScrollPos(Not Horizontal) = NewVal
iSyncing = iSyncing - 1
End If
End Sub
Private Sub Gantt2_OffsetChanged(ByVal Horizontal As Boolean, ByVal NewVal As Long)
If (iSyncing = 0) Then
iSyncing = iSyncing + 1
Gantt1.ScrollPos(Not Horizontal) = NewVal
iSyncing = iSyncing - 1
End If
End Sub
This sample synchronizes the vertical / horizontal scroll bars of both
controls, so when the user scrolls one of the control's content, the other
component is syncing as well.
In order to synchronize the date in the chart portion of the control ( right
side scroll bar ), you need to handle the DateChange event like in the following
sample:
Private Sub Gantt1_DateChange()
If (iSyncing = 0) Then
iSyncing = iSyncing + 1
With Gantt2
.BeginUpdate
.Chart.FirstVisibleDate = Gantt1.Chart.FirstVisibleDate
.EndUpdate
End With
iSyncing = iSyncing - 1
End If
End Sub
Private Sub Gantt2_DateChange()
If (iSyncing = 0) Then
iSyncing = iSyncing + 1
With Gantt1
.BeginUpdate
.Chart.FirstVisibleDate = Gantt2.Chart.FirstVisibleDate
.EndUpdate
End With
iSyncing = iSyncing - 1
End If
End Sub
This snippet of code changes the control's FirstVisibleDate property when the
other's control is calling the DateChange eventd.
Usually it is happen when you load data from a record set. When you call
CellCaption() = rs("Field") the CellCaption property holds a reference to a Field
object not to the field's value. In order to fix that you have to pass the
rs("Field").Value to the CellCaption property as shown in the following sample:
The following code enumerates the records within a recordset, and adds a new item for each record found:
rs.MoveFirst
While Not rs.EOF()
.AddItem rs(0)
rs.MoveNext
Wend
The list shows nothing, so you need to use a code as follows:
rs.MoveFirst
While Not rs.EOF()
.AddItem rs(0).Value
rs.MoveNext
Wend
In conclusion, the rs("Field") returns a reference to an object of Field type, while rs("Field").Value returns the value of the field itself.