GanttChart
A Gantt chart: the plan as a task list beside a timeline of bars, with the links between the tasks, the milestones, the baselines and the critical path, scheduled on a working calendar and editable with the mouse or the keyboard alone.
public partial class GanttChart : Control
Inherits from / implements: Control
Remarks
Use it wherever work is planned against dates – a product launch, a fit-out, a release – to answer what a planner asks of a plan (when does it finish, what is late, which tasks have no slack) and to let them change it by dragging.
The plan
A plan is two lists that belong to the application: Tasks, a flat list of
ProjectTask objects in which a subtask names its summary through
ProjectTask.ParentId, and Links, the TaskLink dependencies
between them – the shape a database table or a spreadsheet already has. An
ObservableCollection is watched, and so is every task and link in it: change a
property and the chart schedules again and redraws.
Scheduling
Dates are worked out by the critical-path method on working days – the days
WorkingWeek names, less the Holidays, from ProjectStart. A
task starts on its planned ProjectTask.Start or as soon as its links allow, whichever
is later, and a summary spans its subtasks. The result is in Schedule, and
ScheduleChanged says when it has been worked out again. Bad data never stops the
chart: a link to a missing task, or a loop, is left out and reported in
ProjectSchedule.Problems, and everything else is drawn.
The two panes
The task list on the left shows the outline and the Columns you choose; the
timeline on the right shows a bar for each task, a diamond for each milestone and a bracket for each
summary, at the scale Zoom sets. The panes scroll up and down together; the splitter
between them sets GridWidth.
Editing
Drag a bar to move the task, its right-hand end to change its length, or the triangle under it
to set its progress; drag from the dot past its end to another row to link the two finish-to-start.
Press F2 to type into the current cell – name, start, days, % done or predecessors (outline numbers
such as 2, 3SS+1). Every edit is offered first through TaskChanging or
LinksChanging, which can cancel it, then made to the task or link object itself and
announced by TaskChanged or LinksChanged. IsReadOnly
allows looking only.
The keyboard
| Keys | What they do |
|---|---|
Up, Down, Home, End, Page Up, Page Down | Move between rows. |
Right, Left | Open or close a summary, or go to its first subtask or back; in other columns, move between cells. |
F2; Enter or Space | Edit the current cell; raise
|
Shift+Left, Shift+Right | Move the task a working day earlier or later. |
Ctrl+Shift+Left, Ctrl+Shift+Right | Make it a working day shorter or longer. |
Ctrl+Plus, Ctrl+Minus, Ctrl+0 | Zoom in, out, or to fit the plan. Esc cancels a drag. |
One plan, three views
Give the same lists to a PertChart and a TaskBoard and the three
agree: they schedule the same objects with the same arithmetic, so a bar dragged here or a card
moved on the board is seen by all of them.
Appearance
The chart draws itself and has no template. Control.Background,
Control.Foreground and the font apply as usual; the bars, links and calendar have
brush properties (BarBrush, CriticalBrush and the rest) whose defaults
read on light and dark backgrounds alike, and in Windows high contrast the system colours replace
them all. The chart always runs left to right, as a calendar does. ExportImage and
Print draw the whole plan.
Examples
A window that plans a website relaunch, built in code so that it stands on its own; in XAML
the lists are bound, as in <pm:GanttChart Tasks="{Binding Tasks}" Links="{Binding Links}"
Zoom="Week" /> with
xmlns:pm="clr-namespace:Binarymission.WPF.Controls.ProjectManagement;assembly=Binarymission.WPF.Controls.ProjectManagement".
using System;
using System.Collections.ObjectModel;
using System.Windows;
using Binarymission.WPF.Controls.ProjectManagement;
public sealed class PlanWindow : Window
{
public PlanWindow()
{
var tasks = new ObservableCollection<ProjectTask>
{
new ProjectTask("design", "Design"), // a summary: it has subtasks
new ProjectTask("wire", "Wireframes", 5) { ParentId = "design", Assignee = "Priya Shah", Progress = 100 },
new ProjectTask("look", "Visual design", 8) { ParentId = "design", Assignee = "Tom Ellis", Progress = 40 },
new ProjectTask("build", "Build"),
new ProjectTask("web", "Front end", 10) { ParentId = "build", Assignee = "Ana Ruiz" },
new ProjectTask("api", "Orders API", 12) { ParentId = "build", Assignee = "Sam Okafor" },
new ProjectTask("live", "Go live", 0), // no length: a milestone
};
var links = new ObservableCollection<TaskLink>
{
new TaskLink("wire", "look"), // finish-to-start
new TaskLink("look", "web", TaskLinkType.StartToStart, 3), // 3 working days after it starts
new TaskLink("wire", "api"),
new TaskLink("web", "live"),
new TaskLink("api", "live"),
};
var gantt = new GanttChart
{
Tasks = tasks,
Links = links,
ProjectStart = new DateTime(2026, 11, 2),
Columns = GanttColumns.Default | GanttColumns.Assignee,
};
gantt.Holidays.Add(new DateTime(2026, 12, 25));
// A finished task stays where it is, whichever way the reader tries to move it.
gantt.TaskChanging += (sender, e) =>
e.Cancel = e.Task.Progress >= 100 && (e.NewStart.HasValue || e.NewDuration.HasValue);
gantt.ScheduleChanged += (sender, e) =>
Title = "Website relaunch - finishes " + gantt.Schedule.ProjectFinish.ToString("d MMM yyyy");
Content = gantt;
Loaded += (sender, e) => gantt.ZoomToFit();
}
}See also
Members at a glance
| Constructors | |
|---|---|
GanttChart | Creates a Gantt chart with an empty plan: empty Tasks, Links
and Holidays lists of its own, a Monday-to-Friday week and Week zoom. To share a plan,
give several charts the same lists. |
| Properties | |
BarBrush | Gets or sets the fill of a task bar and a milestone diamond that are not on the critical path. |
BaselineBrush | Gets or sets the fill of the thin baseline bar drawn under a task's bar while
ShowBaselines is on. |
Columns | Gets or sets which columns the task list shows beside the task's name. |
CriticalBrush | Gets or sets the colour of the bars, milestones and links on the critical path, while
ShowCriticalPath is on. |
GridLineBrush | Gets or sets the colour of the lines between rows and columns, under the headers and beside the splitter. |
GridWidth | Gets or sets the width of the task list, the left-hand pane; the timeline takes the rest. |
HeaderBrush | Gets or sets the tint behind the column headings, the timeline's header rows and the splitter. |
Holidays | Gets or sets the dates that are not worked, beside the days WorkingWeek
leaves out: bank holidays, a shutdown, a company day off. |
IsReadOnly | Gets or sets whether the reader can only look at the plan, and not change it. |
LinkBrush | Gets or sets the colour of the arrows between bars that are not on the critical path. |
Links | Gets or sets the links between the tasks: which task waits for which, how, and with what lag. |
LogicalChildren | Gets the chart's logical children: the scroll bars and the cell editor, which therefore take the chart's resources and styles. |
NonWorkingBrush | Gets or sets the tint behind the days that are not worked – weekends and
Holidays – on the timeline and in its header. |
ProgressBrush | Gets or sets what is painted over the finished part of a bar, from its start to its
ProjectTask.Progress, and over the finished part of a summary's bracket. |
ProjectStart | Gets or sets the first day work on the plan can happen. |
RowHeight | Gets or sets the height of every row, in the task list and on the timeline alike. |
Schedule | Gets the plan as scheduled: every task's dates, float and outline number, the links that were honoured, the critical path, and what in the input could not be used. |
SelectedTask | Gets or sets the task the reader has chosen: the highlighted row and bar, and the row the keyboard works on. |
SelectionBrush | Gets or sets the fill behind the selected row in the task list; a fainter copy marks the row across the timeline. |
ShowBaselines | Gets or sets whether each task's baseline – the dates first agreed – is drawn as a thin bar
in BaselineBrush under its bar, so slippage shows at a glance. |
ShowCriticalPath | Gets or sets whether the critical path – the tasks with no float, which decide when the
plan finishes – is drawn in CriticalBrush, links included. |
ShowLinks | Gets or sets whether the links between tasks are drawn as arrows between their bars. |
ShowToday | Gets or sets whether a line in TodayBrush is drawn down the timeline through
today, with a notch in the header. |
SummaryBrush | Gets or sets the colour of a summary task's bracket: the bar with downward points at each end that spans its subtasks. |
Tasks | Gets or sets the tasks of the plan: a flat list in outline order, in which a subtask names
its summary through ProjectTask.ParentId. |
Today | Gets or sets the date the today line is drawn on. |
TodayBrush | Gets or sets the colour of the today line, the notch above it, and today's date in the header. |
VisualChildrenCount | Gets the number of elements the chart is made of: its three drawing panes, its three scroll bars and its cell editor. |
WeekStart | Gets or sets the day a week begins on in the timeline's headers. |
WorkingWeek | Gets or sets the days of the week on which work happens. |
Zoom | Gets or sets how much time the timeline shows: how wide a day is, and what its two header rows label. |
| Methods | |
ArrangeOverride | Lays out the task list, the splitter, the timeline and the scroll bars in the size the chart has been given. |
CollapseAll | Closes every summary task, leaving the top level of the outline. Raises
TaskToggled for each one closed; a selected subtask hands the selection to its
summary. |
ExpandAll | Opens every summary task, so that every task has a row. Raises TaskToggled
for each one opened. |
ExportImage | Draws the whole chart as an image: every task, inside closed summaries too, beside the whole timeline, with the task list at its full width. |
GetVisualChild | Returns one of the elements the chart is made of. |
IsExpanded | Tells whether a summary task is open, showing its subtasks. |
MeasureOverride | Says how much room the chart wants: all it is given, up to 720 by 360 logical units. |
OnCreateAutomationPeer | Gives UI Automation the chart as a tree of rows, so that a screen reader can read and work the plan. |
OnDpiChanged | Redraws for a new display scale, so that grid lines stay one device pixel wide and text is sharp. |
OnIsKeyboardFocusedChanged | Shows or hides the focus rectangle round the current row, and on taking the focus tells a screen reader which row is current. |
OnKeyDown | Carries out the chart's keys: the arrows and page keys to move between rows and cells, F2 to edit, Enter and Space to activate, Shift and Ctrl+Shift with the arrows to move and stretch a task, Ctrl with Plus, Minus and 0 to zoom, and Esc to cancel a drag. |
OnLinksChanged | Raises LinksChanged. An override should call the base implementation, or
handlers are not called. |
OnLinksChanging | Raises LinksChanging. An override should call the base implementation, or
handlers are not called. |
OnLostMouseCapture | Cancels a drag, with no change, when something else takes the mouse – a dialog, or another window coming to the front. |
OnMouseLeave | Hides the bar handles and the tooltip when the pointer leaves the chart. |
OnMouseLeftButtonDown | Acts on a click: selects the row or bar under the pointer, opens or closes a summary at its
expander, and starts a drag on a bar, its end, its progress handle, its link dot or the splitter. A
double-click raises TaskActivated. |
OnMouseLeftButtonUp | Ends a drag and makes the change it describes, through TaskChanging or
LinksChanging. A press that never moved far enough to be a drag changes
nothing. |
OnMouseMove | Follows the pointer: carries on a drag, scrolling when it passes the edge of the view, or shows the handles of the bar under the pointer and, after the hover time, a tooltip describing its task. |
OnMouseRightButtonDown | Selects the task under the pointer, so that a context menu acts on the task that was clicked. |
OnMouseWheel | Scrolls the rows by the system's wheel setting; with Shift, scrolls the pane under the pointer sideways; with Ctrl, zooms about the pointer. |
OnPropertyChanged | Redraws when a property the drawing reads from the control itself changes: the font,
Foreground,
Background or
UIElement.IsEnabled. |
OnQueryCursor | Shows what a press would do: a sideways arrow over the splitter, a bar's end or its progress handle, a cross over a link dot, and a hand over a bar that can be moved or an expander. |
OnRender | Draws the background, the splitter and the corner above the vertical scroll bar. The task list and the timeline are drawn by panes of their own, so that scrolling or a drag redraws only what changed. |
OnScheduleChanged | Raises ScheduleChanged. An override should call the base implementation, or
handlers are not called. |
OnSelectedTaskChanged | Raises SelectedTaskChanged. An override should call the base implementation,
or handlers are not called. |
OnTaskActivated | Raises TaskActivated. An override should call the base implementation, or
handlers are not called. |
OnTaskChanged | Raises TaskChanged. An override should call the base implementation, or
handlers are not called. |
OnTaskChanging | Raises TaskChanging. An override should call the base implementation, or
handlers are not called. |
OnTaskToggled | Raises TaskToggled. An override should call the base implementation, or
handlers are not called. |
OnZoomChanged | Raises ZoomChanged. An override should call the base implementation, or
handlers are not called. |
Print | Asks the reader for a printer and prints the whole chart on one page, as
ExportImage draws it, shrunk to fit the printable area when it is larger. |
Reschedule | Schedules the plan again now and redraws. |
ScrollToTask | Brings a task into view: opens the summaries above it, scrolls its row into view, and scrolls the timeline to its bar when any of the bar is out of sight. |
ScrollToToday | Scrolls the timeline sideways so that today is in view, a third of the way across the pane. |
SetExpanded | Opens or closes one summary task. |
ZoomIn | Shows less time in more detail: one step finer through Year, Quarter, Month, Week and Day. |
ZoomOut | Shows more time in less detail: one step coarser through Day, Week, Month, Quarter and Year. |
ZoomToFit | Chooses the finest Zoom at which the whole plan, first day to last, fits the
timeline pane, and scrolls to the plan's first day. |
| Events | |
LinksChanged | Occurs after an edit the reader made has added links to Links or removed
them. Save the links here to keep the edit. |
LinksChanging | Occurs when the reader is about to change the links into a task – by drawing a link between two bars, or by typing into the Predecessors cell. Cancel it to refuse the edit. |
ScheduleChanged | Occurs after the plan has been scheduled again: once the chart is loaded, and whenever a task, a link, one of the lists or a calendar setting has changed. |
SelectedTaskChanged | Occurs when SelectedTask changes, whether the reader chose another row or the
application set the property. |
TaskActivated | Occurs when the reader asks to open a task: by double-clicking its row or bar, or by pressing Enter or Space on the selected row. The task is already selected. |
TaskChanged | Occurs after an edit the reader made has been written to a task: its start, length, progress or name. |
TaskChanging | Occurs when the reader is about to change a task – by dragging its bar, by a key or by typing into a cell – before anything has changed. Cancel it to refuse the edit. |
TaskToggled | Occurs when a summary task is opened or closed – by its expander, the arrow keys,
SetExpanded, ExpandAll, CollapseAll, or because a task
inside it was selected. |
ZoomChanged | Occurs when Zoom changes, from code or from the reader's Ctrl+wheel,
Ctrl+Plus, Ctrl+Minus or Ctrl+0. |
| Fields | |
BarBrushProperty | Identifies the BarBrush dependency property. |
BaselineBrushProperty | Identifies the BaselineBrush dependency property. |
ColumnsProperty | Identifies the Columns dependency property. |
CriticalBrushProperty | Identifies the CriticalBrush dependency property. |
GridLineBrushProperty | Identifies the GridLineBrush dependency property. |
GridWidthProperty | Identifies the GridWidth dependency property. |
HeaderBrushProperty | Identifies the HeaderBrush dependency property. |
HolidaysProperty | Identifies the Holidays dependency property. |
IsReadOnlyProperty | Identifies the IsReadOnly dependency property. |
LinkBrushProperty | Identifies the LinkBrush dependency property. |
LinksProperty | Identifies the Links dependency property. |
NonWorkingBrushProperty | Identifies the NonWorkingBrush dependency property. |
ProgressBrushProperty | Identifies the ProgressBrush dependency property. |
ProjectStartProperty | Identifies the ProjectStart dependency property. |
RowHeightProperty | Identifies the RowHeight dependency property. |
SelectedTaskProperty | Identifies the SelectedTask dependency property. |
SelectionBrushProperty | Identifies the SelectionBrush dependency property. |
ShowBaselinesProperty | Identifies the ShowBaselines dependency property. |
ShowCriticalPathProperty | Identifies the ShowCriticalPath dependency property. |
ShowLinksProperty | Identifies the ShowLinks dependency property. |
ShowTodayProperty | Identifies the ShowToday dependency property. |
SummaryBrushProperty | Identifies the SummaryBrush dependency property. |
TasksProperty | Identifies the Tasks dependency property. |
TodayBrushProperty | Identifies the TodayBrush dependency property. |
TodayProperty | Identifies the Today dependency property. |
WeekStartProperty | Identifies the WeekStart dependency property. |
WorkingWeekProperty | Identifies the WorkingWeek dependency property. |
ZoomProperty | Identifies the Zoom dependency property. |
Constructors
GanttChart
Properties
BarBrush
Gets or sets the fill of a task bar and a milestone diamond that are not on the critical path.
- Value
- The default is an opaque mid blue,
#4A8FD6.nullleaves bars unfilled. - Designer category
- Brush
Remarks
Critical bars use CriticalBrush while ShowCriticalPath is on,
and the finished part of every bar is darkened by ProgressBrush. Summaries are drawn
in SummaryBrush. In Windows high contrast the system colours are used
instead.
Example
<pm:GanttChart BarBrush="#2E7D32" CriticalBrush="#C62828" ProgressBrush="#66000000"
TodayBrush="#1565C0" NonWorkingBrush="#14000000" />See also
BaselineBrush
Gets or sets the fill of the thin baseline bar drawn under a task's bar while
ShowBaselines is on.
- Value
- The default is a light grey,
#A3ABB5. - Designer category
- Brush
Remarks
In Windows high contrast the system colours are used instead.
Columns
Gets or sets which columns the task list shows beside the task's name.
- Value
- A combination of
GanttColumnsflags. The default isGanttColumns.Default: outline number, name, start, finish, days and predecessors. The name is always shown.
Remarks
The order is fixed – #, Task, Start, Finish, Days, % done, Assignee, Predecessors – and so
are the English headings. Name, Start, Days, % done and Predecessors can be typed into with F2. For
example GanttColumns.Wbs | GanttColumns.Name | GanttColumns.Assignee.
CriticalBrush
Gets or sets the colour of the bars, milestones and links on the critical path, while
ShowCriticalPath is on.
- Value
- The default is a red-orange,
#E3552F.nulldraws critical bars inBarBrush. - Designer category
- Brush
Remarks
It is also the colour of the border a cell editor shows when what was typed cannot be read. In Windows high contrast the system colours are used instead.
GridLineBrush
Gets or sets the colour of the lines between rows and columns, under the headers and beside the splitter.
- Value
- The default is grey at 20% opacity (
#33808080), which shows on a light or a dark background alike. - Designer category
- Brush
Remarks
In Windows high contrast the system colours are used instead.
GridWidth
Gets or sets the width of the task list, the left-hand pane; the timeline takes the rest.
- Value
- In logical units (1/96 inch). The default is 420.
NaNor an infinity is read as 420, and a negative width as 0, which hides the list.
Remarks
It is never drawn wider than leaves room for the splitter and the vertical scroll bar. Dragging the splitter sets it, keeping both panes at least 48 units wide, without removing a binding; Esc during the drag puts it back.
HeaderBrush
Gets or sets the tint behind the column headings, the timeline's header rows and the splitter.
- Value
- The default is grey at 7% opacity (
#12808080), laid overBackground. - Designer category
- Brush
Remarks
In Windows high contrast the system colours are used instead.
Holidays
Gets or sets the dates that are not worked, beside the days WorkingWeek
leaves out: bank holidays, a shutdown, a company day off.
- Value
- The non-working dates; only the date part of each is read. The default is an empty list of
the chart's own; setting
nullgives a new empty one.
Remarks
A task that runs across a holiday is a day longer on the calendar, and the day is shaded at
Day and Week zoom. An ObservableCollection is watched: gantt.Holidays.Add(new
DateTime(2026, 12, 25)) reschedules at once.
IsReadOnly
Gets or sets whether the reader can only look at the plan, and not change it.
- Value
trueto stop dragging bars, drawing links, typing into cells and keyboard moves. The default isfalse.
Remarks
Selecting, scrolling, zooming, opening summaries and resizing the task list still work, and
code can still change the plan. Turning it on cancels a drag and drops an open edit. To allow some
edits only, cancel TaskChanging instead.
LinkBrush
Gets or sets the colour of the arrows between bars that are not on the critical path.
- Value
- The default is a mid grey,
#87919C.nulldraws them grey. - Designer category
- Brush
Remarks
Links on the critical path use CriticalBrush; the selected task's links are
drawn in Foreground, heavier. In Windows high contrast
the system colours are used instead.
See also
Links
Gets or sets the links between the tasks: which task waits for which, how, and with what lag.
- Value
- The links to schedule with and draw. The default is an empty list of the chart's own; setting
nullgives a new empty one.
Remarks
A link that cannot be honoured – an unknown task, a repeat, a loop – is left out and
reported in ProjectSchedule.Problems. Links the reader draws or types are added to and
removed from this list, which therefore must not be read-only if links are to be edited. It is
watched as Tasks is.
See also
LogicalChildren
Gets the chart's logical children: the scroll bars and the cell editor, which therefore take the chart's resources and styles.
- Value
- An enumerator over the scroll bars and the editor; the drawing panes are not included.
NonWorkingBrush
Gets or sets the tint behind the days that are not worked – weekends and
Holidays – on the timeline and in its header.
- Value
- The default is grey at 9% opacity (
#17808080).nullshades nothing. - Designer category
- Brush
Remarks
The tint is drawn only at Day and Week Zoom, where a day is wide enough to
see. In Windows high contrast the system colours are used instead.
ProgressBrush
Gets or sets what is painted over the finished part of a bar, from its start to its
ProjectTask.Progress, and over the finished part of a summary's bracket.
- Value
- The default is a translucent black (
#5C000000), which darkens whatever colour the bar is, critical or not.nullshows no progress. - Designer category
- Brush
Remarks
A translucent brush keeps working whatever BarBrush and
CriticalBrush are; an opaque one paints the finished part a colour of its own. In
Windows high contrast the system colours are used instead.
ProjectStart
Gets or sets the first day work on the plan can happen.
- Value
- The project's first possible day, or
nullto take it from the tasks: the earliest plannedProjectTask.Start, else the earliest plannedProjectTask.Finish, else today. The default isnull.
Remarks
A date that is not worked is read as the next working day. No task is scheduled before it
except one that TaskConstraintKind.MustStartOn an earlier date.
RowHeight
Gets or sets the height of every row, in the task list and on the timeline alike.
- Value
- In logical units (1/96 inch). The default is 28; values are kept between 16 and 200, and
NaNis read as 28.
Remarks
A bar is half the row high, never less than 6, so taller rows give bars and handles that are easier to grab.
Schedule
Gets the plan as scheduled: every task's dates, float and outline number, the links that were honoured, the critical path, and what in the input could not be used.
- Value
- The current schedule; never
null.
Remarks
A change only marks the schedule stale; it is worked out again when next needed, by a
redraw or by reading this, so the value is always current. A chart that is not loaded schedules
afresh on every read. ScheduledTask.Task leads back to your own task.
Example
foreach (ScheduledTask task in gantt.Schedule.Tasks)
{
if (task.IsCritical && !task.IsSummary)
Console.WriteLine($"{task.Wbs} {task.Name}: {task.Start:d} to {task.Finish:d}");
}See also
SelectedTask
Gets or sets the task the reader has chosen: the highlighted row and bar, and the row the keyboard works on.
- Value
- A task in
Tasks, ornullfor none; the default. It binds two-way by default.
Remarks
Setting a task inside a closed summary opens the summaries above it and scrolls it into
view. A task not in Tasks is not selected: the property is cleared once the plan is
current, as it is when the selected task is removed. Closing the summary the selected task is in
moves the selection to the summary. Bind it to a PertChart's or
TaskBoard's SelectedTask to keep the views in step.
See also
SelectionBrush
Gets or sets the fill behind the selected row in the task list; a fainter copy marks the row across the timeline.
- Value
- The default is
null: the system highlight colour at about a quarter opacity, so the row's text stays readable inForeground. - Designer category
- Brush
Remarks
Choose a light or translucent brush: the selected row's text is drawn over it in the ordinary text colour. In Windows high contrast the system colours are used instead.
ShowBaselines
Gets or sets whether each task's baseline – the dates first agreed – is drawn as a thin bar
in BaselineBrush under its bar, so slippage shows at a glance.
- Value
- The default is
false.
Remarks
A task has a baseline when ProjectTask.BaselineStart is set; it runs to
ProjectTask.BaselineFinish, or covers one day without it.
Example
// Freeze the plan as it stands as the baseline, then show it.
foreach (ScheduledTask scheduled in gantt.Schedule.Tasks)
{
scheduled.Task.BaselineStart = scheduled.Start;
scheduled.Task.BaselineFinish = scheduled.Finish;
}
gantt.ShowBaselines = true;ShowCriticalPath
Gets or sets whether the critical path – the tasks with no float, which decide when the
plan finishes – is drawn in CriticalBrush, links included.
- Value
- The default is
true.
Remarks
Turning it off changes only the colours; the critical tasks are still in
ProjectSchedule.CriticalPath.
ShowLinks
Gets or sets whether the links between tasks are drawn as arrows between their bars.
- Value
- The default is
true.
Remarks
Hiding them does not stop them deciding the dates. A link to a task inside a closed summary is not drawn, and the selected task's links are drawn heaviest.
ShowToday
Gets or sets whether a line in TodayBrush is drawn down the timeline through
today, with a notch in the header.
- Value
- The default is
true.
Remarks
Today is Today, or the computer's date. Nothing is drawn when today is
outside the timeline.
SummaryBrush
Gets or sets the colour of a summary task's bracket: the bar with downward points at each end that spans its subtasks.
- Value
- The default is a slate grey,
#5A6470. - Designer category
- Brush
Remarks
In Windows high contrast the system colours are used instead.
Tasks
Gets or sets the tasks of the plan: a flat list in outline order, in which a subtask names
its summary through ProjectTask.ParentId.
- Value
- The tasks to schedule and draw. The default is an empty list of the chart's own; setting
nullgives a new empty one, so it is nevernull.
Remarks
The list's order is the order of the rows within each summary. A task is a summary when
another task names it as its parent. Tasks with no ProjectTask.Id are left out, and a
repeated id is reported in ProjectSchedule.Problems.
While the chart is loaded an ObservableCollection or a
BindingList<T> is watched, and so is every task in it. A plain List<T> is
read when assigned; call Reschedule after changing one. Assigning a new list cancels a
drag and drops an open cell edit.
Example
gantt.Tasks.Add(new ProjectTask("qa", "Acceptance testing", 4) { ParentId = "build", Assignee = "Lena Fischer" });
gantt.Links.Add(new TaskLink("api", "qa")); // scheduled and drawn with no further callSee also
Today
Gets or sets the date the today line is drawn on.
- Value
- The date to treat as today, or
nullfor the computer's date, read at each redraw. The default isnull.
Remarks
It moves the ShowToday line and the place ScrollToToday goes
to, and no date in the schedule. Set it to show a plan as at a status date.
TodayBrush
Gets or sets the colour of the today line, the notch above it, and today's date in the header.
- Value
- The default is a clear green,
#12A17B. - Designer category
- Brush
Remarks
The line is drawn while ShowToday is on. In Windows high contrast the system
colours are used instead.
VisualChildrenCount
Gets the number of elements the chart is made of: its three drawing panes, its three scroll bars and its cell editor.
- Value
- Always 7.
WeekStart
Gets or sets the day a week begins on in the timeline's headers.
- Value
- The default is Monday.
Remarks
At Week zoom each week is labelled by this day. Scheduling is unaffected;
WorkingWeek decides that.
WorkingWeek
Gets or sets the days of the week on which work happens.
- Value
- A combination of day flags. The default is
WorkingWeek.Weekdays, Monday to Friday;WorkingWeek.Noneis read as every day.
Remarks
Durations and lags count working days, so a five-day task starting on a Thursday finishes
the Wednesday after, and the weekend between is shaded. In XAML: WorkingWeek="Sunday, Monday,
Tuesday, Wednesday, Thursday".
See also
Zoom
Gets or sets how much time the timeline shows: how wide a day is, and what its two header rows label.
- Value
- The default is
GanttZoom.Week; a value outsideGanttZoomis read as Week.
Remarks
A day is 32 logical units (1/96 inch) wide at Day, 14 at Week, 4 at Month, 1.6 at Quarter
and 0.6 at Year; weekends and holidays are shaded at Day and Week. A change keeps the date in the
middle of the timeline (or under the pointer, for Ctrl+wheel) where it is, and raises
ZoomChanged.
See also
Methods
ArrangeOverride
Lays out the task list, the splitter, the timeline and the scroll bars in the size the chart has been given.
Parameters
arrangeSize- The final size, in logical units.
Returns
arrangeSize: the chart uses all of it.
Remarks
Scrolls asked for before the first layout – by ZoomToFit,
ScrollToTask and the rest – are carried out once this has run.
CollapseAll
Closes every summary task, leaving the top level of the outline. Raises
TaskToggled for each one closed; a selected subtask hands the selection to its
summary.
ExpandAll
Opens every summary task, so that every task has a row. Raises TaskToggled
for each one opened.
ExportImage
Draws the whole chart as an image: every task, inside closed summaries too, beside the whole timeline, with the task list at its full width.
Parameters
dpi- The resolution in dots per inch; 96, the default, gives one pixel per logical unit, and 192 an image twice as sharp for print.
Returns
The image, frozen, so that it can be saved or handed to another thread.
Exceptions
ArgumentOutOfRangeExceptiondpiis not a positive number.
Remarks
Selection, focus and the scroll position are not drawn, and the image uses the chart's current
Zoom, colours and font. The chart need not be on screen: one made only for exporting
reads its plan afresh.
An image that would be wider or taller than 16,384 pixels, or larger than 128 megapixels, is
made at the highest resolution below dpi that fits; its
DpiX says which.
Example
BitmapSource image = gantt.ExportImage(144);
var png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(image));
using (FileStream file = File.Create("Relaunch plan.png"))
png.Save(file);See also
GetVisualChild
Returns one of the elements the chart is made of.
Parameters
index- From 0 to
VisualChildrenCount– 1, in drawing order: the task list, the timeline, the overlay, then the scroll bars and the editor.
Returns
The element at that position.
Exceptions
ArgumentOutOfRangeExceptionindexis outside that range.
IsExpanded
Tells whether a summary task is open, showing its subtasks.
Parameters
task- The task to ask about.
Returns
true for an open summary; false for a closed one, a
task with no subtasks, null, or a task not in the plan.
MeasureOverride
Says how much room the chart wants: all it is given, up to 720 by 360 logical units.
Parameters
constraint- The room available, in logical units; either side may be infinite.
Returns
The smaller of constraint and 720 by 360.
Remarks
A chart shows as much of a plan as fits and scrolls the rest, so it has no natural size;
give it a size, or put it where it is stretched (a Grid cell or a
DockPanel's last child), rather than in a StackPanel.
OnCreateAutomationPeer
Gives UI Automation the chart as a tree of rows, so that a screen reader can read and work the plan.
Returns
The chart's automation peer.
Remarks
Each row is a tree item named with what its bar shows in pictures – its dates, length,
progress, and its float or that it is critical – and can be selected, opened or closed, scrolled
into view and invoked (which raises TaskActivated).
OnDpiChanged
Redraws for a new display scale, so that grid lines stay one device pixel wide and text is sharp.
Parameters
oldDpi- The scale before.
newDpi- The scale now.
OnIsKeyboardFocusedChanged
Shows or hides the focus rectangle round the current row, and on taking the focus tells a screen reader which row is current.
Parameters
e- The old and new values of
UIElement.IsKeyboardFocused.
OnKeyDown
Carries out the chart's keys: the arrows and page keys to move between rows and cells, F2 to edit, Enter and Space to activate, Shift and Ctrl+Shift with the arrows to move and stretch a task, Ctrl with Plus, Minus and 0 to zoom, and Esc to cancel a drag.
Parameters
e- The key. Keys the chart uses are marked handled; others, and any key with Alt, are left for the window.
Remarks
The arrows are always taken, even at the first or last row, so they never move focus out of the chart by surprise. The class remarks list every key.
OnLinksChanged
Raises LinksChanged. An override should call the base implementation, or
handlers are not called.
Parameters
e- Empty event data.
OnLinksChanging
Raises LinksChanging. An override should call the base implementation, or
handlers are not called.
Parameters
e- The proposed change; set
CancelEventArgs.Cancelto refuse it.
OnLostMouseCapture
Cancels a drag, with no change, when something else takes the mouse – a dialog, or another window coming to the front.
Parameters
e- The event data.
OnMouseLeave
Hides the bar handles and the tooltip when the pointer leaves the chart.
Parameters
e- The event data.
OnMouseLeftButtonDown
Acts on a click: selects the row or bar under the pointer, opens or closes a summary at its
expander, and starts a drag on a bar, its end, its progress handle, its link dot or the splitter. A
double-click raises TaskActivated.
Parameters
e- The click.
Remarks
A click while a cell is being edited first commits the edit; when the text cannot be read, the editor stays open and the click does nothing more. An override should call the base implementation.
OnMouseLeftButtonUp
Ends a drag and makes the change it describes, through TaskChanging or
LinksChanging. A press that never moved far enough to be a drag changes
nothing.
Parameters
e- The release.
OnMouseMove
Follows the pointer: carries on a drag, scrolling when it passes the edge of the view, or shows the handles of the bar under the pointer and, after the hover time, a tooltip describing its task.
Parameters
e- The move.
OnMouseRightButtonDown
Selects the task under the pointer, so that a context menu acts on the task that was clicked.
Parameters
e- The click. It is left unhandled, so the chart's
FrameworkElement.ContextMenustill opens.
Example
<pm:GanttChart x:Name="gantt">
<pm:GanttChart.ContextMenu>
<ContextMenu>
<MenuItem Header="Open task" Click="OnOpenTask" /> <!-- acts on gantt.SelectedTask -->
</ContextMenu>
</pm:GanttChart.ContextMenu>
</pm:GanttChart>OnMouseWheel
Scrolls the rows by the system's wheel setting; with Shift, scrolls the pane under the pointer sideways; with Ctrl, zooms about the pointer.
Parameters
e- The wheel turn.
OnPropertyChanged
Redraws when a property the drawing reads from the control itself changes: the font,
Foreground,
Background or
UIElement.IsEnabled.
Parameters
e- The property that changed, with its old and new values.
Remarks
An override should call the base implementation.
OnQueryCursor
Shows what a press would do: a sideways arrow over the splitter, a bar's end or its progress handle, a cross over a link dot, and a hand over a bar that can be moved or an expander.
Parameters
e- The event data, whose
Cursoris set.
OnRender
Draws the background, the splitter and the corner above the vertical scroll bar. The task list and the timeline are drawn by panes of their own, so that scrolling or a drag redraws only what changed.
Parameters
drawingContext- Where to draw.
OnScheduleChanged
Raises ScheduleChanged. An override should call the base implementation, or
handlers are not called.
Parameters
e- Empty event data.
OnSelectedTaskChanged
Raises SelectedTaskChanged. An override should call the base implementation,
or handlers are not called.
Parameters
e- Empty event data.
OnTaskActivated
Raises TaskActivated. An override should call the base implementation, or
handlers are not called.
Parameters
e- The task that was activated.
OnTaskChanged
Raises TaskChanged. An override should call the base implementation, or
handlers are not called.
Parameters
e- The task that changed.
OnTaskChanging
Raises TaskChanging. An override should call the base implementation, or
handlers are not called.
Parameters
e- The proposed change; set
CancelEventArgs.Cancelto refuse it.
OnTaskToggled
Raises TaskToggled. An override should call the base implementation, or
handlers are not called.
Parameters
e- The summary that was opened or closed.
OnZoomChanged
Raises ZoomChanged. An override should call the base implementation, or
handlers are not called.
Parameters
e- Empty event data.
Asks the reader for a printer and prints the whole chart on one page, as
ExportImage draws it, shrunk to fit the printable area when it is larger.
Parameters
description- The name of the job in the printer's queue;
nullor empty for "Gantt chart".
Remarks
Nothing is printed if the reader cancels the print dialog. A long plan at a fine zoom is
shrunk a long way; choose a coarser Zoom first, or close summaries, for a readable
page.
Reschedule
Schedules the plan again now and redraws.
Remarks
Needed only after changing a plain List<T> or array, or a task in one;
observable collections and their tasks are watched. Tasks newly added to a plain list are watched
from here on. ScheduleChanged is raised before this returns.
ScrollToTask
Brings a task into view: opens the summaries above it, scrolls its row into view, and scrolls the timeline to its bar when any of the bar is out of sight.
Parameters
task- The task to show. Nothing happens for
nullor a task that is not in the plan.
Remarks
The selection does not change; set SelectedTask as well to highlight it.
Called before the chart has a size, it waits for the first layout.
Example
ProjectTask late = gantt.Schedule.Tasks.First(t => t.TotalFloat < 0).Task;
gantt.SelectedTask = late;
gantt.ScrollToTask(late);ScrollToToday
Scrolls the timeline sideways so that today is in view, a third of the way across the pane.
Remarks
Today is Today, or the computer's date. The rows do not scroll. Called before
the chart has a size, it waits for the first layout.
SetExpanded
Opens or closes one summary task.
Parameters
task- The summary. Nothing happens for
null, a task not in the plan, or one with no subtasks. expandedtrueto show its subtasks;falseto hide them.
Remarks
Raises TaskToggled when the summary changes. Closing one that holds the
selected task moves the selection to it.
ZoomIn
Shows less time in more detail: one step finer through Year, Quarter, Month, Week and Day.
Remarks
The date in the middle of the timeline stays where it is. At Day zoom nothing changes. The reader's Ctrl+Plus does the same, and Ctrl with the wheel zooms about the pointer.
See also
ZoomOut
Shows more time in less detail: one step coarser through Day, Week, Month, Quarter and Year.
Remarks
The date in the middle of the timeline stays where it is. At Year zoom nothing changes. The reader's Ctrl+Minus does the same.
See also
ZoomToFit
Chooses the finest Zoom at which the whole plan, first day to last, fits the
timeline pane, and scrolls to the plan's first day.
Remarks
Called before the chart has a size – from a constructor, say – it waits for the first layout and then fits. An empty plan is left as it is. When even Year zoom is too fine the chart is set to Year. The reader's Ctrl+0 does the same.
Example
gantt.Loaded += (sender, e) => gantt.ZoomToFit();Events
LinksChanged
Occurs after an edit the reader made has added links to Links or removed
them. Save the links here to keep the edit.
See also
LinksChanging
Occurs when the reader is about to change the links into a task – by drawing a link between two bars, or by typing into the Predecessors cell. Cancel it to refuse the edit.
Remarks
Drawing adds one link; typing replaces the links into the task that differ from the ones typed,
keeping those typed as they already are. A link the scheduler would
refuse – a loop, a repeat, a summary linked to its own subtask – never gets this far: the reader is
told why instead. When nobody cancels, the links are removed from and added to Links
and LinksChanged is raised. When Links is read-only the reader is told
so, and the event is not raised.
See also
ScheduleChanged
Occurs after the plan has been scheduled again: once the chart is loaded, and whenever a task, a link, one of the lists or a calendar setting has changed.
Remarks
Changes that arrive together – a board re-ranking a column, a loop setting twenty
properties – are scheduled once and announced once, from the dispatcher, so a handler sees the
finished result and may change the plan again. Reschedule raises it before returning.
A chart that is not loaded does not raise it.
Example
gantt.ScheduleChanged += (sender, e) =>
{
finishText.Text = gantt.Schedule.ProjectFinish.ToLongDateString();
problemList.ItemsSource = gantt.Schedule.Problems; // each one reads as a sentence
};SelectedTaskChanged
Occurs when SelectedTask changes, whether the reader chose another row or the
application set the property.
TaskActivated
Occurs when the reader asks to open a task: by double-clicking its row or bar, or by pressing Enter or Space on the selected row. The task is already selected.
Example
gantt.TaskActivated += (sender, e) => MessageBox.Show($"{e.Task.Name}: {e.Task.Assignee}, {e.Task.Progress:0}% done");TaskChanged
Occurs after an edit the reader made has been written to a task: its start, length, progress or name.
Remarks
Raised once per edit, before the plan is scheduled again; save the task here to keep the
edit, and read the dates that follow from it in ScheduleChanged.
See also
TaskChanging
Occurs when the reader is about to change a task – by dragging its bar, by a key or by typing into a cell – before anything has changed. Cancel it to refuse the edit.
Remarks
The event data names the task, how the edit was made and the new values
(null for what is not changing). When nobody cancels, the chart writes the values
to the ProjectTask, raises TaskChanged and schedules again. Every edit
the chart makes comes through here, which makes it the one place for rules such as "a signed-off
task cannot move"; setting a task's properties in code does not raise it.
A moved task keeps its TaskConstraintKind.StartNoEarlierThan
constraint, so a bar dropped earlier than its links allow is drawn where the links put it.
Example
gantt.TaskChanging += (sender, e) =>
{
if (e.Task.Status == "Signed off")
{
e.Cancel = true;
MessageBox.Show(e.Task.Name + " is signed off and cannot be changed.");
}
};See also
TaskToggled
Occurs when a summary task is opened or closed – by its expander, the arrow keys,
SetExpanded, ExpandAll, CollapseAll, or because a task
inside it was selected.
Remarks
Raised once for each summary that changes. Which summaries are open belongs to the chart:
ProjectTask.IsCollapsed only sets how a summary starts, and is not written
back.
ZoomChanged
Occurs when Zoom changes, from code or from the reader's Ctrl+wheel,
Ctrl+Plus, Ctrl+Minus or Ctrl+0.
Fields
BarBrushProperty static
Identifies the BarBrush dependency property.
BaselineBrushProperty static
Identifies the BaselineBrush dependency property.
ColumnsProperty static
Identifies the Columns dependency property.
CriticalBrushProperty static
Identifies the CriticalBrush dependency property.
GridLineBrushProperty static
Identifies the GridLineBrush dependency property.
GridWidthProperty static
Identifies the GridWidth dependency property.
HeaderBrushProperty static
Identifies the HeaderBrush dependency property.
HolidaysProperty static
Identifies the Holidays dependency property.
IsReadOnlyProperty static
Identifies the IsReadOnly dependency property.
LinkBrushProperty static
Identifies the LinkBrush dependency property.
LinksProperty static
Identifies the Links dependency property.
NonWorkingBrushProperty static
Identifies the NonWorkingBrush dependency property.
ProgressBrushProperty static
Identifies the ProgressBrush dependency property.
ProjectStartProperty static
Identifies the ProjectStart dependency property.
RowHeightProperty static
Identifies the RowHeight dependency property.
SelectedTaskProperty static
Identifies the SelectedTask dependency property.
SelectionBrushProperty static
Identifies the SelectionBrush dependency property.
ShowBaselinesProperty static
Identifies the ShowBaselines dependency property.
ShowCriticalPathProperty static
Identifies the ShowCriticalPath dependency property.
ShowLinksProperty static
Identifies the ShowLinks dependency property.
ShowTodayProperty static
Identifies the ShowToday dependency property.
SummaryBrushProperty static
Identifies the SummaryBrush dependency property.
TasksProperty static
Identifies the Tasks dependency property.
TodayBrushProperty static
Identifies the TodayBrush dependency property.
TodayProperty static
Identifies the Today dependency property.
WeekStartProperty static
Identifies the WeekStart dependency property.
WorkingWeekProperty static
Identifies the WorkingWeek dependency property.
ZoomProperty static
Identifies the Zoom dependency property.