HypernovaDesktop Components · docs
Binarymission
WinForms › Project Management › ProjectTask

ProjectTask

class.NET 6 / 8 / 10.NET Framework 4.8Binarymission.WinForms.Controls.ProjectManagement

One row of a project plan – a piece of work, a summary that groups other tasks, or a milestone – as the Gantt chart, the PERT chart and the task board all read it.

public class ProjectTask : INotifyPropertyChanged

Inherits from / implements: INotifyPropertyChanged

Remarks

What it is for

A plan is a flat list of these with parent references, plus a list of TaskLink objects between them: the shape a database table, a spreadsheet export or a web service already has. Give the same two collections to a GanttChart, a PertChart and a TaskBoard and they show one plan. Every property raises PropertyChanged, so a bar dragged on the Gantt chart or a card moved on the board is seen by the other charts at once, because they are all looking at the same objects.

Three kinds of task

  • Work has a Duration in working days (or a Start and Finish it is measured from).
  • A summary is any task that another task names as its ParentId. Its dates, length and progress are rolled up from its subtasks, so its own Duration is not used; a Start on a summary still holds all of its subtasks back.
  • A milestone has a Duration of zero, or IsMilestone set. It marks a moment – a sign-off, a release – and is drawn as a diamond.

Dates

The charts do not keep dates of their own: they schedule the plan by the critical-path method (ProjectScheduler) and draw the result, so Start and Finish are what was planned, and ScheduledTask.Start and ScheduledTask.Finish are what the links allow. Only the date part of a DateTime is kept, so a value read from a database as midnight UTC and one typed as a local date plan the same day. Durations and lags count working days on the plan's calendar.

Board fields

Status is the task board's column, and Assignee and Category are the fields it can split its lanes by. Rank is a card's order within its column. None of these move a date.

Examples

A small website plan: two phases, a stand-alone task and a launch milestone. The phases are summaries because other tasks name them as their parent.

using System;
using System.Collections.ObjectModel;

ObservableCollection<ProjectTask> tasks = new ObservableCollection<ProjectTask>
{
    new ProjectTask("design", "Design"),                     // summary: no duration of its own
    new ProjectTask("brief", "Agree the brief", 3)
    {
        ParentId = "design",
        Start = new DateTime(2026, 11, 2),
        Assignee = "Priya",
        Status = "Done",
        Progress = 100
    },
    new ProjectTask("wire", "Wireframes", 5) { ParentId = "design", Assignee = "Priya", Status = "In progress", Progress = 40 },

    new ProjectTask("build", "Build"),
    new ProjectTask("front", "Front end", 10) { ParentId = "build", Assignee = "Tom", Status = "To do" },
    new ProjectTask("api", "Order API", 8) { ParentId = "build", Assignee = "Aisha", Status = "To do" },

    new ProjectTask("test", "User testing", 4) { Assignee = "Priya", Status = "To do" },
    new ProjectTask("live", "Go live", 0) { Status = "To do" }   // a milestone
};

See also

Members at a glance

Constructors
ProjectTaskCreates an empty task. Give it at least an Id; a task without one is left out of the plan.
ProjectTaskCreates a task with an id, a name and, optionally, a length in working days.
Properties
AssigneeGets or sets who is doing the work.
BaselineFinishGets or sets the originally agreed last working day, the other end of the baseline.
BaselineStartGets or sets the originally agreed start, kept so the Gantt chart can show how far the task has moved since.
CategoryGets or sets a grouping of the application's choosing, such as a workstream or a cost centre.
ConstraintGets or sets how the task's own Start or Finish holds it, in addition to its links.
DurationGets or sets the task's length in working days.
FinishGets or sets the planned last working day of the task.
IdGets or sets the identifier that links, subtasks and every chart event refer to the task by.
IsCollapsedGets or sets whether a summary task starts closed on the Gantt chart, with its subtasks hidden.
IsMilestoneGets or sets whether the task is a milestone – a moment with no length, drawn as a diamond – whatever its Duration says.
NameGets or sets what the task is called: the text of its row, bar label, box and card, and what a screen reader announces.
ParentIdGets or sets the Id of the summary task this task sits under in the outline.
ProgressGets or sets how much of the task is done, as a percentage.
RankGets or sets the card's position within its column on the task board, lower first.
StartGets or sets the planned start: the earliest date the task may begin.
StatusGets or sets the task's workflow state, such as "To do", "In progress" or "Done".
TagGets or sets any object the application wants to keep with the task, such as the database row it came from.
Methods
CloneCreates a shallow copy of the task, with every property, Tag included.
OnPropertyChangedRaises PropertyChanged. A derived task with properties of its own calls this from their setters so the charts see those changes too.
ToStringReturns the task's name, for the debugger and for list boxes.
Events
PropertyChangedOccurs when any property of the task changes. The charts listen to it to redraw.

Constructors

ProjectTask

public ProjectTask()

Creates an empty task. Give it at least an Id; a task without one is left out of the plan.

ProjectTask

public ProjectTask(string id, string name, int? duration

Creates a task with an id, a name and, optionally, a length in working days.

Parameters
id
The task's id, unique in its plan. It is what TaskLink objects and other tasks' ParentId refer to.
name
What the task is called on every chart.
duration
Length in working days; zero makes a milestone. Leave it out (null) for a summary task, or for a task whose length comes from its Start and Finish.
Example
ProjectTask phase = new ProjectTask("build", "Build");                     // a summary
ProjectTask work = new ProjectTask("api", "Order API", 8) { ParentId = "build" };
ProjectTask signOff = new ProjectTask("signoff", "Client sign-off", 0);   // a milestone

Properties

Assignee

public string Assignee

Gets or sets who is doing the work.

Value
Any text, such as a person's name. The default is null.
Remarks

The Gantt chart can show it in a column (GanttColumns.Assignee), a task board card shows its initials, and a board whose lanes are by BoardLaneBy.Assignee has a lane per assignee; dropping a card in another lane sets this property.

BaselineFinish

public DateTime? BaselineFinish

Gets or sets the originally agreed last working day, the other end of the baseline.

Value
A date; only its date part is kept. The default is null.
See also

BaselineStart

public DateTime? BaselineStart

Gets or sets the originally agreed start, kept so the Gantt chart can show how far the task has moved since.

Value
A date; only its date part is kept. The default is null: no baseline.
Remarks

Drawn as a thin bar under the task's bar, from this date to BaselineFinish (one day long when that is not set), when GanttChart.ShowBaselines is on. Nothing is scheduled from it.

Example

Recording the plan as agreed, once it has been scheduled, so later slippage shows.

ProjectSchedule agreed = ProjectScheduler.Schedule(tasks, links);
foreach (ScheduledTask scheduled in agreed.Tasks)
{
    scheduled.Task.BaselineStart = scheduled.Start;
    scheduled.Task.BaselineFinish = scheduled.Finish;
}

Category

public string Category

Gets or sets a grouping of the application's choosing, such as a workstream or a cost centre.

Value
Any text. The default is null.
Remarks

A task board whose lanes are by BoardLaneBy.Category has a lane per category, and dropping a card in another lane sets this property. Nothing else reads it.

Constraint

public TaskConstraintKind Constraint

Gets or sets how the task's own Start or Finish holds it, in addition to its links.

Value
The default is TaskConstraintKind.StartNoEarlierThan.
Example
// The venue is booked for 14 December: the launch event happens then, whatever slips before it.
ProjectTask launch = new ProjectTask("event", "Launch event", 1)
{
    Start = new DateTime(2026, 12, 14),
    Constraint = TaskConstraintKind.MustStartOn
};

Duration

public int? Duration

Gets or sets the task's length in working days.

Value
A whole number of working days; zero makes the task a milestone, and a negative value is read as zero. The default is null: the length is then the working days from Start to Finish inclusive when both are set, and otherwise one day.
Remarks

Weekends and holidays do not count, so a five-day task that starts on a Thursday finishes on the following Wednesday. A summary's own duration is not used: its length is rolled up from its subtasks.

When a chart changes the duration – a bar's end dragged, a cell typed – it clears Finish as well, unless Constraint is TaskConstraintKind.FinishNoEarlierThan, so the two never say different things.

Finish

public DateTime? Finish

Gets or sets the planned last working day of the task.

Value
A date; only its date part is kept. The default is null.
Remarks

It is read in two cases only: to measure the length of a task whose Duration is null, and as the date a TaskConstraintKind.FinishNoEarlierThan constraint holds. Otherwise the finish is worked out from the start and the duration, and is ScheduledTask.Finish.

Id

public string Id

Gets or sets the identifier that links, subtasks and every chart event refer to the task by.

Value
Any string, compared exactly (case matters). The default is null.
Remarks

A task whose id is null is left out of the plan without comment. When two tasks share an id, the first one in the list is used and the other is reported as ScheduleProblemKind.DuplicateTask.

Changing the id of a task that links or subtasks already refer to leaves them pointing at the old id; change those references too.

See also

IsCollapsed

public bool IsCollapsed

Gets or sets whether a summary task starts closed on the Gantt chart, with its subtasks hidden.

Value
The default is false: summaries start open. It has no effect on a task that is not a summary.
Remarks

It is read only until the reader opens or closes the summary; the chart then remembers the reader's choice and does not write it back here.

IsMilestone

public bool IsMilestone

Gets or sets whether the task is a milestone – a moment with no length, drawn as a diamond – whatever its Duration says.

Value
true to make a milestone. The default is false; a task with a duration of zero is a milestone either way.

Name

public string Name

Gets or sets what the task is called: the text of its row, bar label, box and card, and what a screen reader announces.

Value
Any text. The default is null, in which case the charts show the Id.

ParentId

public string ParentId

Gets or sets the Id of the summary task this task sits under in the outline.

Value
The parent's id, or null (the default) or an empty string for a top-level task.
Remarks

Naming a task as a parent is what makes it a summary: its dates are then rolled up from its subtasks. An id that is not in the plan puts the task at the top level and is reported as ScheduleProblemKind.UnknownParent; a parent that would make the task its own ancestor is reported as ScheduleProblemKind.ParentCycle and is ignored in the same way.

On a task board whose lanes are by phase (BoardLaneBy.Parent), dropping a card in another lane sets this to that phase's id.

Progress

public double Progress

Gets or sets how much of the task is done, as a percentage.

Value
From 0 to 100. The default is 0. The value is stored as given; when the plan is scheduled a value below 0 is read as 0, above 100 as 100, and NaN or infinity as 0.
Remarks

A summary's own progress is not used: ScheduledTask.Progress for a summary is its subtasks' progress weighted by their durations.

Rank

public double? Rank

Gets or sets the card's position within its column on the task board, lower first.

Value
Any number. The default is null: cards without a rank follow the ranked ones, in the order the tasks are listed.
Remarks

The board writes this when a card is moved, renumbering every card in the cell it lands in from 1 upwards. Nothing else reads it, so rearranging a board never moves a date.

Start

public DateTime? Start

Gets or sets the planned start: the earliest date the task may begin.

Value
A date; only its date part is kept. The default is null, which lets the task start as soon as its links, its summary and the project's start allow.
Remarks

Links may push the task later than this date, never earlier – unless Constraint is TaskConstraintKind.MustStartOn, which holds the task to it. A weekend or holiday is read as the next working day.

Dragging a bar on the Gantt chart, or typing in its Start cell, sets this property. The date the task is actually scheduled on is ScheduledTask.Start.

See also

Status

public string Status

Gets or sets the task's workflow state, such as "To do", "In progress" or "Done".

Value
Any text, compared exactly. The default is null.
Remarks

The task board's columns are statuses: a card sits in the column whose BoardColumn.Status matches this value, or in the first column when none does, and moving a card sets it. The Gantt and PERT charts do not read it.

Tag

public object Tag

Gets or sets any object the application wants to keep with the task, such as the database row it came from.

Value
The default is null. The charts never read it.

Methods

Clone

public ProjectTask Clone()

Creates a shallow copy of the task, with every property, Tag included.

Returns

A new task with the same values. Tag refers to the same object as the original's.

Remarks

Handlers attached to the original's PropertyChanged event are not carried over: the copy starts with none.

OnPropertyChanged

protected virtual void OnPropertyChanged(string propertyName)

Raises PropertyChanged. A derived task with properties of its own calls this from their setters so the charts see those changes too.

Parameters
propertyName
The name of the property that changed.

ToString

public override string ToString()

Returns the task's name, for the debugger and for list boxes.

Returns

The Name, or the Id when the name is empty, or an empty string when the task has neither.

Events

PropertyChanged

public event PropertyChangedEventHandler PropertyChanged

Occurs when any property of the task changes. The charts listen to it to redraw.

Remarks

Raised only when a value actually changes; setting a property to the value it already has raises nothing.