Back to Devexpress

Task Dependencies

windowsforms-401713-controls-and-libraries-gantt-control-task-dependencies.md

latest19.3 KB
Original Source

Task Dependencies

  • Sep 03, 2021
  • 9 minutes to read

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

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

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

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

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

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.

csharp
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;
}
vb
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()

Private Function GetTasks() As DataTable
    Dim table As New DataTable()
    Dim id As New DataColumn("ID", GetType(Integer))
    Dim parentId As New DataColumn("ParentID", GetType(Integer))
    Dim taskText As New DataColumn("Text", GetType(String))
    Dim start As New DataColumn("StartDate", GetType(DateTime))
    Dim finish As New DataColumn("FinishDate", GetType(DateTime))
    Dim predecessors As New DataColumn("Predecessors", GetType(String))
    table.Columns.AddRange(New DataColumn() {id, parentId, taskText, start, finish, predecessors})
    table.Rows.Add(New Object() { 1, 0, "Task 1", DateTime.Now, DateTime.Now.AddDays(1), Nothing })
    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(1), DateTime.Now.AddDays(2), "1, 2" })
    Return table
End Function

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.

csharp
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;
}
vb
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()

Private Function GetTasks() As DataTable
    Dim table As New DataTable()
    Dim id As New DataColumn("ID", GetType(Integer))
    Dim parentId As New DataColumn("ParentID", GetType(Integer))
    Dim taskText As New DataColumn("Text", GetType(String))
    Dim start As New DataColumn("StartDate", GetType(DateTime))
    Dim finish As New DataColumn("FinishDate", GetType(DateTime))
    table.Columns.AddRange(New DataColumn() {id, parentId, taskText, 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
End Function

Private Function GetDependencies() As DataTable
    Dim table As New DataTable()
    Dim predecessor As New DataColumn("PredecessorID", GetType(Integer))
    Dim successor As New DataColumn("SuccessorID", GetType(Integer))
    Dim dependencyType As New DataColumn("DependencyType", GetType(DevExpress.XtraGantt.DependencyType))
    Dim lag As New DataColumn("TimeLag", GetType(TimeSpan))
    table.Columns.AddRange(New DataColumn() {predecessor, successor, dependencyType, lag})
    table.Rows.Add(New Object() {1, 2, DevExpress.XtraGantt.DependencyType.StartToFinish, New TimeSpan(12, 0, 0)})
    table.Rows.Add(New Object() {2, 3, DevExpress.XtraGantt.DependencyType.StartToStart, Nothing})
    Return table
End Function

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.

csharp
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();
vb
Imports DevExpress.XtraGantt
Imports System.Collections.Generic

' The following methods return nodes that specify a task's predecessors and successors.
Dim predecessorNodes = 
    ganttControl1.GetPredecessorNodes(0)
Dim predecessorNodes1 As IEnumerable(Of GanttControlNode) = 
    ganttControl1.GetPredecessorNodes(TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 2"), GanttControlNode))
Dim predecessorNodes2 As IEnumerable(Of GanttControlNode) = 
    TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 3"), GanttControlNode).GetPredecessorNodes()

Dim successorNodes = 
    ganttControl1.GetSuccessorNodes(0)
Dim successorNodes1 As IEnumerable(Of GanttControlNode) = 
    ganttControl1.GetSuccessorNodes(TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 2"), GanttControlNode))
Dim successorNodes2 As IEnumerable(Of GanttControlNode) = 
    TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 3"), 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.
Dim predecessorKeyList As List(Of Object) = 
    TryCast(ganttControl1.GetPredecessors(0), List(Of Object))
Dim predecessorsKeyList1 As List(Of Object) = 
    TryCast(ganttControl1.GetPredecessors(TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 2"), GanttControlNode)), List(Of Object))
Dim predecessorsKeyList2 As List(Of Object) = 
    TryCast(TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 3"), GanttControlNode).GetPredecessors(), List(Of Object))

Dim successorKeyList As List(Of Object) = 
    TryCast(ganttControl1.GetSuccessors(0), List(Of Object))
Dim successorsKeyList1 As List(Of Object) = 
    TryCast(ganttControl1.GetSuccessors(TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 2"), GanttControlNode)), List(Of Object))
Dim successorsKeyList2 As List(Of Object) = 
    TryCast(TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 3"), GanttControlNode).GetSuccessors(), List(Of 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.
Dim predecessorKeys = 
    ganttControl1.GetPredecessors(0)
Dim predecessorsKeys1 = 
    ganttControl1.GetPredecessors(TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 2"), GanttControlNode))
Dim predecessorsKeys2 = 
    TryCast(ganttControl1.FindNodeByFieldValue("Text", "Task 3"), GanttControlNode).GetPredecessors()

See Also

Interactive Editing