Skip to main content

Task Dependencies

  • 9 minutes to read

The Gantt control can display task dependencies of the following types:

  • FinishToStart — a successor should start when its predecessor finishes.

    image

  • FinishToFinish — a successor should finish when its predecessor finishes.

    image

  • StartToFinish — a successor should finish when its predecessor starts.

    image

  • StartToStart — a successor should start when its predecessor starts.

    image

How to Specify Dependencies

To specify dependencies, use data source fields. If you only need finish-to-start dependencies, you can use the same data source for tasks and dependencies. If you need all dependency types, use a separate data source for dependencies.

Finish-to-Start Dependency Type

If you only need the finish-to-start dependency type, use the GanttControl.DataSource property to specify the data source that contains tasks and dependencies. A data record represents a task and contains information about its caption, start and finish dates, duration, and predecessors. The GanttControl.ChartMappings property provides access to the PredecessorsFieldName property to specify a task’s predecessors.

The code below shows how to specify tasks and dependencies.

image

ganttControl1.TreeListMappings.KeyFieldName = "ID";
ganttControl1.TreeListMappings.ParentFieldName = "ParentID";
ganttControl1.ChartMappings.TextFieldName = "Text";
ganttControl1.ChartMappings.StartDateFieldName = "StartDate";
ganttControl1.ChartMappings.FinishDateFieldName = "FinishDate";
ganttControl1.ChartMappings.PredecessorsFieldName = "Predecessors";
ganttControl1.DataSource = GetTasks();

DataTable GetTasks() {
    DataTable table = new DataTable();
    DataColumn id = new DataColumn("ID", typeof(int));
    DataColumn parentId = new DataColumn("ParentID", typeof(int));
    DataColumn text = new DataColumn("Text", typeof(string));
    DataColumn start = new DataColumn("StartDate", typeof(DateTime));
    DataColumn finish = new DataColumn("FinishDate", typeof(DateTime));
    DataColumn predecessors = new DataColumn("Predecessors", typeof(string));
    table.Columns.AddRange(new DataColumn[] { id, parentId, text, start, finish, predecessors });
    table.Rows.Add(new object[] { 1, 0, "Task 1", DateTime.Now, DateTime.Now.AddDays(1), null });
    table.Rows.Add(new object[] { 2, 0, "Task 2", DateTime.Now.AddDays(1), DateTime.Now.AddDays(2), 1 });
    table.Rows.Add(new object[] { 3, 0, "Task 3", DateTime.Now.AddDays(2), DateTime.Now.AddDays(3), "1, 2"});
    return table;
}

See Bind to Data Source for more information about data source mappings.

All Dependency Types

If you need all dependency types, use the GanttControl.DependencySource property to specify the data source that contains dependencies. A data record represents a dependency and specifies its type, predecessor, successor, etc. The GanttControl.DependencyMappings property provides access to the following properties:

  • PredecessorFieldName — specifies a predecessor task’s key.
  • SuccessorFieldName — specifies a successor task’s key.
  • TypeFieldName — specifies the dependency type (finish-to-start, finish-to-finish, etc.).
  • LagFieldName — specifies the time lag between the successor and the predecessor. If a user moves a predecessor, the control automatically reschedules all its successors with respect to the time lag.

Note

If you use these properties and the GanttControl.DependencySource property to specify dependencies, dependencies specified with the PredecessorsFieldName and GanttControl.DataSource properties are not in effect.

The code below shows how to specify tasks and dependencies.

image

using DevExpress.XtraGantt;

ganttControl1.TreeListMappings.KeyFieldName = "ID";
ganttControl1.TreeListMappings.ParentFieldName = "ParentID";
ganttControl1.ChartMappings.TextFieldName = "Text";
ganttControl1.ChartMappings.StartDateFieldName = "StartDate";
ganttControl1.ChartMappings.FinishDateFieldName = "FinishDate";
ganttControl1.DataSource = GetTasks();

ganttControl1.DependencyMappings.PredecessorFieldName = "PredecessorID";
ganttControl1.DependencyMappings.SuccessorFieldName = "SuccessorID";
ganttControl1.DependencyMappings.TypeFieldName = "DependencyType";
ganttControl1.DependencyMappings.LagFieldName = "TimeLag";
ganttControl1.DependencySource = GetDependencies();

DataTable GetTasks() {
    DataTable table = new DataTable();
    DataColumn id = new DataColumn("ID", typeof(int));
    DataColumn parentId = new DataColumn("ParentID", typeof(int));
    DataColumn text = new DataColumn("Text", typeof(string));
    DataColumn start = new DataColumn("StartDate", typeof(DateTime));
    DataColumn finish = new DataColumn("FinishDate", typeof(DateTime));
    table.Columns.AddRange(new DataColumn[] { id, parentId, text, start, finish });
    table.Rows.Add(new object[] { 1, 0, "Task 1", DateTime.Now, DateTime.Now.AddDays(1) });
    table.Rows.Add(new object[] { 2, 0, "Task 2", DateTime.Now.AddDays(1), DateTime.Now.AddDays(2) });
    table.Rows.Add(new object[] { 3, 0, "Task 3", DateTime.Now.AddDays(2), DateTime.Now.AddDays(3) });
    return table;
}

DataTable GetDependencies() {
    DataTable table = new DataTable();
    DataColumn predecessor = new DataColumn("PredecessorID", typeof(int));
    DataColumn successor = new DataColumn("SuccessorID", typeof(int));
    DataColumn dependencyType = new DataColumn("DependencyType", typeof(DevExpress.XtraGantt.DependencyType));
    DataColumn lag = new DataColumn("TimeLag", typeof(TimeSpan));
    table.Columns.AddRange(new DataColumn[] { predecessor, successor, dependencyType, lag });
    table.Rows.Add(new object[] { 1, 2, DependencyType.StartToFinish, new TimeSpan(12, 0, 0) });
    table.Rows.Add(new object[] { 2, 3, DependencyType.StartToStart, null });
    return table;
}

Modify Dependencies

If the AllowModifyDependencies option is enabled, users can modify dependencies. See Interactive Editing for more information.

Obtain Dependencies in Code

Use the methods below to obtain a task’s predecessors. You can use a GanttControlNode object or Id property value to specify the task.

Use the methods below to obtain a task’s successors. You can use a GanttControlNode object or Id property value to specify the task.

Example

The example below shows how to get a task’s predecessors and successors. You can use the FindNodeByFieldValue(String, Object) method to retrieve a GanttControlNode object by the content in a specific field.

using DevExpress.XtraGantt;
using System.Collections.Generic;

// The following methods return nodes that specify a task's predecessors and successors.
IEnumerable<GanttControlNode> predecessorNodes = 
    ganttControl1.GetPredecessorNodes(0);
IEnumerable<GanttControlNode> predecessorNodes1 = 
    ganttControl1.GetPredecessorNodes(ganttControl1.FindNodeByFieldValue("Text", "Task 2") as GanttControlNode);
IEnumerable<GanttControlNode> predecessorNodes2 = 
    (ganttControl1.FindNodeByFieldValue("Text", "Task 3") as GanttControlNode).GetPredecessorNodes();

IEnumerable<GanttControlNode> successorNodes = 
    ganttControl1.GetSuccessorNodes(0);
IEnumerable<GanttControlNode> successorNodes1 = 
    ganttControl1.GetSuccessorNodes(ganttControl1.FindNodeByFieldValue("Text", "Task 2") as GanttControlNode);
IEnumerable<GanttControlNode> successorNodes2 = 
    (ganttControl1.FindNodeByFieldValue("Text", "Task 3") as GanttControlNode).GetSuccessorNodes();

// The following methods return keys
// (as they are specified in the data source) of a task's predecessors and successors.
// If you use the DependencySource property to specify dependencies,
// the returned value is of List<object> type. Items in the collection are keys of the corresponding type.
List<object> predecessorKeyList = 
    ganttControl1.GetPredecessors(0) as List<object>;
List<object> predecessorsKeyList1 = 
    ganttControl1.GetPredecessors(ganttControl1.FindNodeByFieldValue("Text", "Task 2") as GanttControlNode) as List<object>;
List<object> predecessorsKeyList2 = 
    (ganttControl1.FindNodeByFieldValue("Text", "Task 3") as GanttControlNode).GetPredecessors() as List<object>;

List<object> successorKeyList = 
    ganttControl1.GetSuccessors(0) as List<object>;
List<object> successorsKeyList1 = 
    ganttControl1.GetSuccessors(ganttControl1.FindNodeByFieldValue("Text", "Task 2") as GanttControlNode) as List<object>;
List<object> successorsKeyList2 = 
    (ganttControl1.FindNodeByFieldValue("Text", "Task 3") as GanttControlNode).GetSuccessors() as List<object>;

// If you use the DataSource property to specify dependencies,
// the returned value is of the same type as in the data source.
// Note that you cannot get successors in this case
// since the data source stores predecessors only.
var predecessorKeys = 
    ganttControl1.GetPredecessors(0);
var predecessorsKeys1 = 
    ganttControl1.GetPredecessors(ganttControl1.FindNodeByFieldValue("Text", "Task 2") as GanttControlNode);
var predecessorsKeys2 = 
    (ganttControl1.FindNodeByFieldValue("Text", "Task 3") as GanttControlNode).GetPredecessors();
See Also