HypernovaDesktop Components · docs
Binarymission
WPF › Project Management › ProjectScheduler

ProjectScheduler

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

Schedules a project plan by the critical-path method: works out every task's earliest and latest dates on a working calendar, its float, and the chain of tasks that decides when the plan finishes.

public static class ProjectScheduler

Remarks

What it is for

This is the engine behind the GanttChart, the PertChart and the TaskBoard: each chart schedules its plan through it and draws the result, so the three always agree. Call it yourself to work with the same dates without a chart – a report, an export, a check on the server before a plan is saved.

How a plan is scheduled

  1. The outline is read: each task finds its parent, and every task gets an outline number (ScheduledTask.Wbs).
  2. Each task's own dates are read: its duration in working days, its planned start and any ProjectTask.Constraint.
  3. The links are checked, and any that cannot be honoured are reported and left out.
  4. The forward pass gives every task its earliest dates: as soon as its links, its summary, its planned start and the project's start allow.
  5. The backward pass gives every task its latest dates: as late as it can be without moving the project's finish.
  6. Float, the critical path and summaries' progress are worked out from the two.

Bad data is never fatal

A duplicate id, a link to a task that is not there, a loop of links: each is reported in ProjectSchedule.Problems and left out, and everything else is still scheduled. The scheduler does not throw for anything in the plan.

Working days

Durations and lags count working days on the calendar of ScheduleInput.WorkingDays and ScheduleInput.Holidays, so a five-day task that starts on a Thursday finishes on the following Wednesday. Dates have no time of day and no time zone, so a plan schedules to the same dates on every machine.

Examples

A website plan of eight tasks, scheduled on a Monday-to-Friday week from Monday 2 November 2026. The comments give the dates the scheduler works out.

using System;
using System.Collections.Generic;

List<ProjectTask> tasks = new List<ProjectTask>
{
    new ProjectTask("design", "Design"),                                   // summary
    new ProjectTask("brief", "Agree the brief", 3) { ParentId = "design" },
    new ProjectTask("wire", "Wireframes", 5) { ParentId = "design" },
    new ProjectTask("build", "Build"),                                     // summary
    new ProjectTask("front", "Front end", 10) { ParentId = "build" },
    new ProjectTask("api", "Order API", 8) { ParentId = "build" },
    new ProjectTask("test", "User testing", 4),
    new ProjectTask("live", "Go live", 0)                                  // milestone
};

List<TaskLink> links = new List<TaskLink>
{
    new TaskLink("brief", "wire"),
    new TaskLink("wire", "front"),
    new TaskLink("wire", "api", TaskLinkType.StartToStart, 2),
    new TaskLink("build", "test"),                                         // after all of Build
    new TaskLink("test", "live")
};

ProjectSchedule schedule = ProjectScheduler.Schedule(tasks, links, new DateTime(2026, 11, 2));

// brief  Mon 2 Nov  - Wed 4 Nov
// wire   Thu 5 Nov  - Wed 11 Nov
// api    Mon 9 Nov  - Wed 18 Nov   (5 working days of float)
// front  Thu 12 Nov - Wed 25 Nov
// test   Thu 26 Nov - Tue 1 Dec
// live   Tue 1 Dec
Console.WriteLine(schedule.ProjectFinish.ToString("yyyy-MM-dd"));      // 2026-12-01
Console.WriteLine(string.Join(" > ", schedule.CriticalPath));         // brief > wire > front > test > live
Console.WriteLine(schedule.Find("api").TotalFloat);                   // 5

foreach (ScheduleProblem problem in schedule.Problems)
{
    Console.WriteLine(problem.Message);                                // none for this plan
}

See also

Members at a glance

Methods
CodeReturns the two-letter code a planner writes a link type as, and the Gantt chart's Predecessors column uses.
ScheduleSchedules a plan with full control of the calendar: the tasks, the links, the project's first day, the working week and the holidays.
ScheduleSchedules a plan from its tasks and links on a Monday-to-Friday week with no holidays.

Methods

Code static

public static string Code(TaskLinkType type)

Returns the two-letter code a planner writes a link type as, and the Gantt chart's Predecessors column uses.

Parameters
type
The link type.
Returns

FS, SS, FF or SF. A value that is not a TaskLinkType gives FS.

Schedule static

public static ProjectSchedule Schedule(ScheduleInput input)

Schedules a plan with full control of the calendar: the tasks, the links, the project's first day, the working week and the holidays.

Parameters
input
The plan and its calendar. Null schedules an empty plan.
Returns

The scheduled plan; never null. Anything in the input that could not be used is in its ProjectSchedule.Problems.

Remarks

The input's collections are read once, during the call; the result does not follow later changes to them. Nothing in the input is changed.

Example
ProjectSchedule schedule = ProjectScheduler.Schedule(new ScheduleInput
{
    Tasks = tasks,
    Links = links,
    ProjectStart = new DateTime(2026, 11, 2),
    Holidays = new[] { new DateTime(2026, 12, 25), new DateTime(2026, 12, 28) }
});

Schedule static

public static ProjectSchedule Schedule(IEnumerable<ProjectTask> tasks, IEnumerable<TaskLink> links

Schedules a plan from its tasks and links on a Monday-to-Friday week with no holidays.

Parameters
tasks
The tasks, in outline order within each parent. Null schedules an empty plan.
links
The links between them; null for none.
projectStart
The first day work can happen; null to take it from the tasks (the earliest planned start, then the earliest planned finish, and failing both, today).
Returns

The scheduled plan; never null.

Remarks

The same as Schedule() with no working days or holidays set.