windowsforms-401744-controls-and-libraries-gantt-control-getting-started.md
This tutorial shows how to use the GanttControl — how to populate it with data, specify the workweek schedule, allow users to modify tasks in the chart, enable a modal form to edit tasks in the task list, and how to customize task appearance.
Create a new project in Visual Studio. Drop the GanttControl from the Toolbox window onto the main application form.
In the control’s smart tag menu, click Create Ribbon and Dock in Parent Container to add the ribbon with chart commands to the form and make the Gantt control fill all the available space.
You can bind the control to a data source in code or in the designer. Use the following properties to assign a data source to the control:
DataSource — specifies the data source that contains tasks. The TreeListMappings and ChartMappings specify data source fields that contain the following data:
DependencySource — specifies the data source that contains dependencies. This data source allows you to support all dependency types. The DependencyMappings specify data source fields that contain the following data:
The GanttControl supports the same binding modes as the TreeList. See Data Binding for details on how to bind the TreeList to a data source. For more information about mapping to data source fields in the GanttControl, see the Bind to Data Source topic. For general information about binding DevExpress controls to data sources, see Data Binding Common Concepts.
This tutorial shows how to bind the control to a sample business object and data exported from Microsoft Project.
Note
Make sure that you specified all required mappings. Otherwise, specific functionality may not be available. See the following topic for more information: Bind to Data Source.
Important
If you use all three time-related task properties (StartDateFieldName, FinishDateFieldName, Duration), make sure the Duration does not conflict with Start and Finish dates. Since the control draws tasks depending on Start and Finish dates, these conflicts can be masked until you try to edit a task. For example:
This setup introduces a conflict: the 24-hour task duration means a task should span across three days (eight working hours a day), which mismatches StartDate-FinishDate values. The control will draw a 24-hour task based on Start and Finish dates, but the 3-day duration will be stored internally, and will cause issues when a task is edited.
You can use business objects to store data. The example below creates a collection of Task objects and assigns it to the DataSource property. The data source also contains information about finish-to-start dependencies between tasks.
The resulting application window is shown in the figure below.
using System;
using System.ComponentModel;
using System.Collections.Generic;
ganttControl1.TreeListMappings.KeyFieldName = "Id";
ganttControl1.TreeListMappings.ParentFieldName = "ParentId";
ganttControl1.ChartMappings.TextFieldName = "Name";
ganttControl1.ChartMappings.StartDateFieldName = "StartDate";
ganttControl1.ChartMappings.FinishDateFieldName = "FinishDate";
ganttControl1.ChartMappings.DurationFieldName = "Duration";
ganttControl1.ChartMappings.PredecessorsFieldName = "Predecessors";
ganttControl1.ChartMappings.ProgressFieldName = "Progress";
ganttControl1.DataSource = LoadData();
public static IList<Task> LoadData() {
var tasks = new List<Task>();
Task softwareDevelopment = new Task("Software Development", 0, -1, DateTime.Now, 1, 24);
Task analyseRequirements = new Task("Analyse Requirements", 1, softwareDevelopment.Id, softwareDevelopment.StartDate, 1, 100);
Task developFunctionalSpecifications = new Task("Develop functional specifications", 2, softwareDevelopment.Id, analyseRequirements.FinishDate, 1, 100, 1);
Task developSoftware = new Task("Develop software", 3, softwareDevelopment.Id, developFunctionalSpecifications.FinishDate, 5, 40, developFunctionalSpecifications.Id);
Task developHelpSystem = new Task("Develop help system", 4, softwareDevelopment.Id, developFunctionalSpecifications.FinishDate, 1, 90, developFunctionalSpecifications.Id);
Task developUserManuals = new Task("Develop user manuals", 5, softwareDevelopment.Id, developHelpSystem.FinishDate, 1, 0, developHelpSystem.Id);
Task testSoftware = new Task("Test software", 6, softwareDevelopment.Id, developSoftware.FinishDate, 2, 0, developSoftware.Id);
Task deployBeta = new Task("Deploy Beta", 7, softwareDevelopment.Id, testSoftware.FinishDate, 0, 0, testSoftware.Id);
Task collectFeedback = new Task("Collect feedback", 8, softwareDevelopment.Id, deployBeta.FinishDate, 2, 0, deployBeta.Id);
Task fixBugs = new Task("Fix bugs", 9, softwareDevelopment.Id, collectFeedback.FinishDate, 2, 0, collectFeedback.Id);
Task incorporateFeedBack = new Task("Incorporate feedback", 10, softwareDevelopment.Id, collectFeedback.FinishDate, 3, 0, collectFeedback.Id);
Task releaseSoftware = new Task("Release software", 11, softwareDevelopment.Id, incorporateFeedBack.FinishDate, 2, 0, fixBugs.Id, incorporateFeedBack.Id);
Task createSoftwareMaintenanceTeam = new Task("Create software maintenance team", 12, softwareDevelopment.Id, deployBeta.FinishDate, 1, 0, developSoftware.Id);
Task softwareDevelopmentComplete = new Task("Software development complete", 13, softwareDevelopment.Id, releaseSoftware.FinishDate, 0, 0, releaseSoftware.Id);
softwareDevelopment.FinishDate = softwareDevelopmentComplete.FinishDate;
tasks.AddRange(new Task[] {softwareDevelopment, analyseRequirements, developFunctionalSpecifications, developSoftware, developHelpSystem, developUserManuals,
testSoftware,deployBeta,collectFeedback, fixBugs, incorporateFeedBack, releaseSoftware, createSoftwareMaintenanceTeam, softwareDevelopmentComplete });
return tasks;
}
public class Task{
public Task(string name, int id, int parentId, DateTime start, int duration, double progress, params int[] predecessors) {
Name = name;
Id = id;
ParentId = parentId;
StartDate = start;
Duration = TimeSpan.FromDays(duration);
FinishDate = start + Duration;
Progress = progress;
Predecessors = new BindingList<int>();
foreach (int predecessor in predecessors) {
Predecessors.Add(predecessor);
}
}
public int Id { get; set; }
public int ParentId { get; set; }
public BindingList<int> Predecessors { get; private set; }
public string Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime FinishDate { get; set; }
public TimeSpan Duration { get; set; }
public double Progress { get; set; }
}
Imports System
Imports System.ComponentModel
Imports System.Collections.Generic
ganttControl1.TreeListMappings.KeyFieldName = "Id"
ganttControl1.TreeListMappings.ParentFieldName = "ParentId"
ganttControl1.ChartMappings.TextFieldName = "Name"
ganttControl1.ChartMappings.StartDateFieldName = "StartDate"
ganttControl1.ChartMappings.FinishDateFieldName = "FinishDate"
ganttControl1.ChartMappings.DurationFieldName = "Duration"
ganttControl1.ChartMappings.PredecessorsFieldName = "Predecessors"
ganttControl1.ChartMappings.ProgressFieldName = "Progress"
ganttControl1.DataSource = LoadData()
Public Shared Function LoadData() As IList(Of Task)
Dim tasks = New List(Of Task)()
Dim softwareDevelopment As New Task("Software Development", 0, -1, DateTime.Now, 1, 24)
Dim analyseRequirements As New Task("Analyse Requirements", 1, softwareDevelopment.Id, softwareDevelopment.StartDate, 1, 100)
Dim developFunctionalSpecifications As New Task("Develop functional specifications", 2, softwareDevelopment.Id, analyseRequirements.FinishDate, 1, 100, 1)
Dim developSoftware As New Task("Develop software", 3, softwareDevelopment.Id, developFunctionalSpecifications.FinishDate, 5, 40, developFunctionalSpecifications.Id)
Dim developHelpSystem As New Task("Develop help system", 4, softwareDevelopment.Id, developFunctionalSpecifications.FinishDate, 1, 90, developFunctionalSpecifications.Id)
Dim developUserManuals As New Task("Develop user manuals", 5, softwareDevelopment.Id, developHelpSystem.FinishDate, 1, 0, developHelpSystem.Id)
Dim testSoftware As New Task("Test software", 6, softwareDevelopment.Id, developSoftware.FinishDate, 2, 0, developSoftware.Id)
Dim deployBeta As New Task("Deploy Beta", 7, softwareDevelopment.Id, testSoftware.FinishDate, 0, 0, testSoftware.Id)
Dim collectFeedback As New Task("Collect feedback", 8, softwareDevelopment.Id, deployBeta.FinishDate, 2, 0, deployBeta.Id)
Dim fixBugs As New Task("Fix bugs", 9, softwareDevelopment.Id, collectFeedback.FinishDate, 2, 0, collectFeedback.Id)
Dim incorporateFeedBack As New Task("Incorporate feedback", 10, softwareDevelopment.Id, collectFeedback.FinishDate, 3, 0, collectFeedback.Id)
Dim releaseSoftware As New Task("Release software", 11, softwareDevelopment.Id, incorporateFeedBack.FinishDate, 2, 0, fixBugs.Id, incorporateFeedBack.Id)
Dim createSoftwareMaintenanceTeam As New Task("Create software maintenance team", 12, softwareDevelopment.Id, deployBeta.FinishDate, 1, 0, developSoftware.Id)
Dim softwareDevelopmentComplete As New Task("Software development complete", 13, softwareDevelopment.Id, releaseSoftware.FinishDate, 0, 0, releaseSoftware.Id)
softwareDevelopment.FinishDate = softwareDevelopmentComplete.FinishDate
tasks.AddRange(New Task() {softwareDevelopment, analyseRequirements, developFunctionalSpecifications, developSoftware, developHelpSystem, developUserManuals,
testSoftware, deployBeta, collectFeedback, fixBugs, incorporateFeedBack, releaseSoftware, createSoftwareMaintenanceTeam, softwareDevelopmentComplete})
Return tasks
End Function
Public Class Task
Public Sub New(ByVal taskName As String, ByVal taskId As Integer, ByVal taskParentId As Integer, ByVal start As DateTime,
ByVal taskDuration As Integer, ByVal taskProgress As Double, ParamArray ByVal predecessorIds() As Integer)
Me.Name = taskName
Me.Id = taskId
Me.ParentId = taskParentId
StartDate = start
Me.Duration = TimeSpan.FromDays(taskDuration)
FinishDate = start.Add(Me.Duration)
Me.Progress = taskProgress
Me.Predecessors = New BindingList(Of Integer)()
For Each predecessor As Integer In predecessorIds
Me.Predecessors.Add(predecessor)
Next predecessor
End Sub
Public Property Id() As Integer
Public Property ParentId() As Integer
Private privatePredecessors As BindingList(Of Integer)
Public Property Predecessors() As BindingList(Of Integer)
Get
Return privatePredecessors
End Get
Private Set(ByVal value As BindingList(Of Integer))
privatePredecessors = value
End Set
End Property
Public Property Name() As String
Public Property StartDate() As DateTime
Public Property FinishDate() As DateTime
Public Property Duration() As TimeSpan
Public Property Progress() As Double
End Class
To use data from Microsoft Project, export data to a file and then convert the data to an appropriate format. In this example, data is stored in a DataTable. To store dependencies, this example uses a separate data source assigned to the DependencySource property.
Save a project as a tab-delimited text file.
Select tasks. Do not include headers. Click Next.
Select data fields to export in the following order: ID , WBS (work breakdown structure), Name , Start , Finish , Predecessors , Resource Names. Click Finish.
This tutorial uses the Software Development Plan template from Microsoft Project. The first three lines contain the following data:
0 0 Software Development 4/21/20 8:00 AM 9/1/20 3:00 PM
1 1 Scope 4/21/20 8:00 AM 4/24/20 12:00 PM
2 1.1 Determine project scope 4/21/20 8:00 AM 4/21/20 12:00 PM Management
Use the following code to create tables that contain data from the file. The resulting application window is shown in the figure below.
using DevExpress.XtraGantt;
using System;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
// Specify data fields that contain
// information about tasks required for
// the control to display the project.
ganttControl1.TreeListMappings.KeyFieldName = "ID";
ganttControl1.TreeListMappings.ParentFieldName = "ParentID";
ganttControl1.ChartMappings.StartDateFieldName = "StartDate";
ganttControl1.ChartMappings.FinishDateFieldName = "FinishDate";
ganttControl1.ChartMappings.TextFieldName = "Resources";
// Specify data fields that contain
// information about dependencies between tasks.
ganttControl1.DependencyMappings.PredecessorFieldName = "PredecessorID";
ganttControl1.DependencyMappings.SuccessorFieldName = "SuccessorID";
ganttControl1.DependencyMappings.TypeFieldName = "Type";
// Specify the path to the exported project.
string path = "c:\\export\\project1.txt";
DataTable tasks = new DataTable();
DataTable dependencies = new DataTable();
PopulateDataSources(path, ref tasks, ref dependencies);
ganttControl1.DataSource = tasks;
ganttControl1.DependencySource = dependencies;
public static void PopulateDataSources(string path, ref DataTable tasks, ref DataTable dependencies) {
// Create columns for the table that contains tasks.
DataColumn colId = new DataColumn("ID", typeof(string));
DataColumn colParentId = new DataColumn("ParentID", typeof(string));
DataColumn colText = new DataColumn("Text", typeof(string));
DataColumn colStart = new DataColumn("StartDate", typeof(DateTime));
DataColumn colFinish = new DataColumn("FinishDate", typeof(DateTime));
DataColumn colDuration = new DataColumn("Duration", typeof(TimeSpan));
DataColumn colResources = new DataColumn("Resources", typeof(string));
DataColumn colWbs = new DataColumn("WBS", typeof(string));
tasks.Columns.AddRange(new DataColumn[] { colId, colParentId, colText, colStart, colFinish, colDuration, colResources, colWbs });
// Create columns for the table that contains dependencies.
DataColumn colPredecessor = new DataColumn("PredecessorID", typeof(string));
DataColumn colSuccessor = new DataColumn("SuccessorID", typeof(string));
DataColumn colType = new DataColumn("Type", typeof(DevExpress.XtraGantt.DependencyType));
dependencies.Columns.AddRange(new DataColumn[] { colPredecessor, colSuccessor, colType });
// Read from the file.
using (StreamReader sr = new StreamReader(path)) {
while (sr.Peek() >= 0) {
string line = sr.ReadLine();
string[] values = line.Split('\t');
string taskId = values[0];
// Get parent ID for each task
// from the work breakdown structure
// used in MS Project.
string taskParentId = string.Empty;
string[] pathWbs = values[1].Split('.');
if (pathWbs.Length == 1)
taskParentId = "0";
else {
string parentWbs = string.Join(".", pathWbs.Take(pathWbs.Length - 1));
foreach (DataRow row in tasks.Rows) {
string rowWbs = (string)row[colWbs];
if (rowWbs == parentWbs) {
taskParentId = (string)row[colId];
}
}
}
// Convert strings to DateTime structures.
DateTime taskStartDate = DateTime.Parse(values[3], CultureInfo.CurrentCulture);
DateTime taskFinishDate = DateTime.Parse(values[4], CultureInfo.CurrentCulture);
// This example calculates the duration
// instead of importing it from the file.
TimeSpan taskDuration = taskFinishDate - taskStartDate;
// Add a new row with the values to the table.
tasks.Rows.Add(new object[] {
taskId,
taskParentId,
values[2], // Text.
taskStartDate,
taskFinishDate,
taskDuration,
values[6], // Resource Names.
values[1] // Work breakdown structure.
});
string[] taskPredecessors = taskPredecessors = values[5].Split(',');
if (taskPredecessors.Length > 0) {
foreach (string value in taskPredecessors) {
DependencyType dependencyType = DependencyType.FinishToStart;
string predecessorId = value;
if (value.Contains("FS")) {
dependencyType = DependencyType.FinishToStart;
predecessorId = value.Substring(0, value.IndexOf("FS"));
// This example ignores the time lag.
string timeLag = value.Substring(value.IndexOf("FS") + 2, value.Length - value.IndexOf("FS") - 2);
}
if (value.Contains("FF")) {
dependencyType = DependencyType.FinishToFinish;
predecessorId = value.Substring(0, value.IndexOf("FF"));
}
if (value.Contains("SS")) {
dependencyType = DependencyType.StartToStart;
predecessorId = value.Substring(0, value.IndexOf("SS"));
}
if (value.Contains("SF")) {
dependencyType = DependencyType.StartToFinish;
predecessorId = value.Substring(0, value.IndexOf("SF"));
}
dependencies.Rows.Add(new object[] { predecessorId, taskId, dependencyType });
}
}
}
}
}
Imports DevExpress.XtraGantt
Imports System
Imports System.Data
Imports System.Globalization
Imports System.IO
Imports System.Linq
' Specify data fields that contain
' information about tasks required for
' the control to display the project.
ganttControl1.TreeListMappings.KeyFieldName = "ID"
ganttControl1.TreeListMappings.ParentFieldName = "ParentID"
ganttControl1.ChartMappings.TextFieldName = "Resources"
ganttControl1.ChartMappings.StartDateFieldName = "StartDate"
ganttControl1.ChartMappings.FinishDateFieldName = "FinishDate"
' Specify data fields that contain
' information about dependencies between tasks.
ganttControl1.DependencyMappings.PredecessorFieldName = "PredecessorID"
ganttControl1.DependencyMappings.SuccessorFieldName = "SuccessorID"
ganttControl1.DependencyMappings.TypeFieldName = "Type"
Dim path As String = "c:\export\project1.txt"
Dim tasks As New DataTable()
Dim dependencies As New DataTable()
PopulateDataSources(path, tasks, dependencies)
ganttControl1.DataSource = tasks
ganttControl1.DependencySource = dependencies
Public Sub PopulateDataSources(ByVal path As String, ByRef tasks As DataTable, ByRef dependencies As DataTable)
' Create columns for the table that contains tasks.
Dim colId As New DataColumn("ID", GetType(String))
Dim colParentId As New DataColumn("ParentID", GetType(String))
Dim colText As New DataColumn("Text", GetType(String))
Dim colStart As New DataColumn("StartDate", GetType(DateTime))
Dim colFinish As New DataColumn("FinishDate", GetType(DateTime))
Dim colDuration As New DataColumn("Duration", GetType(TimeSpan))
Dim colResources As New DataColumn("Resources", GetType(String))
Dim colWbs As New DataColumn("WBS", GetType(String))
tasks.Columns.AddRange(New DataColumn() { colId, colParentId, colText, colStart, colFinish, colDuration, colResources, colWbs })
' Create columns for the table that contains dependencies.
Dim colPredecessor As New DataColumn("PredecessorID", GetType(String))
Dim colSuccessor As New DataColumn("SuccessorID", GetType(String))
Dim colType As New DataColumn("Type", GetType(DevExpress.XtraGantt.DependencyType))
dependencies.Columns.AddRange(New DataColumn() { colPredecessor, colSuccessor, colType })
' Read from the file.
Using sr As New StreamReader(path)
Do While sr.Peek() >= 0
Dim line As String = sr.ReadLine()
Dim values() As String = line.Split(ControlChars.Tab)
Dim taskId As String = values(0)
' Get parent ID for each task
' from the work breakdown structure
' used in MS Project.
Dim taskParentId As String = String.Empty
Dim pathWbs() As String = values(1).Split("."c)
If pathWbs.Length = 1 Then
taskParentId = "0"
Else
Dim parentWbs As String = String.Join(".", pathWbs.Take(pathWbs.Length - 1))
For Each row As DataRow In tasks.Rows
Dim rowWbs As String = DirectCast(row(colWbs), String)
If rowWbs = parentWbs Then
taskParentId = DirectCast(row(colId), String)
End If
Next row
End If
' Convert strings to DateTime structures.
Dim taskStartDate As DateTime = DateTime.Parse(values(3), CultureInfo.CurrentCulture)
Dim taskFinishDate As DateTime = DateTime.Parse(values(4), CultureInfo.CurrentCulture)
' This example calculates the duration
' instead of importing it from the file.
Dim taskDuration As TimeSpan = taskFinishDate.Subtract(taskStartDate)
' Add a new row with the values to the table.
tasks.Rows.Add(New Object() { taskId, taskParentId, values(2), taskStartDate, taskFinishDate, taskDuration, values(6), values(1) })
Dim taskPredecessors() As String = values(5).Split(","c)
If taskPredecessors.Length > 0 Then
For Each value As String In taskPredecessors
Dim dependencyType As DependencyType = DevExpress.XtraGantt.DependencyType.FinishToStart
Dim predecessorId As String = value
If value.Contains("FS") Then
dependencyType = DevExpress.XtraGantt.DependencyType.FinishToStart
predecessorId = value.Substring(0, value.IndexOf("FS"))
' This example ignores the time lag.
Dim timeLag As String = value.Substring(value.IndexOf("FS") + 2, value.Length - value.IndexOf("FS") - 2)
End If
If value.Contains("FF") Then
dependencyType = DevExpress.XtraGantt.DependencyType.FinishToFinish
predecessorId = value.Substring(0, value.IndexOf("FF"))
End If
If value.Contains("SS") Then
dependencyType = DevExpress.XtraGantt.DependencyType.StartToStart
predecessorId = value.Substring(0, value.IndexOf("SS"))
End If
If value.Contains("SF") Then
dependencyType = DevExpress.XtraGantt.DependencyType.StartToFinish
predecessorId = value.Substring(0, value.IndexOf("SF"))
End If
dependencies.Rows.Add(New Object() { predecessorId, taskId, dependencyType })
Next value
End If
Loop
End Using
End Sub
Users can use cell editors to edit tasks in the task list.
You can enable a modal form instead of cell editors or allow users to edit tasks in the chart.
To allow users to modify tasks in the chart, enable the following options:
ganttControl1.OptionsCustomization.AllowModifyTasks = DevExpress.Utils.DefaultBoolean.True;
ganttControl1.OptionsCustomization.AllowModifyProgress = DevExpress.Utils.DefaultBoolean.True;
ganttControl1.OptionsCustomization.AllowModifyDependencies = DevExpress.Utils.DefaultBoolean.True;
ganttControl1.OptionsCustomization.AllowModifyTasks = DevExpress.Utils.DefaultBoolean.True
ganttControl1.OptionsCustomization.AllowModifyProgress = DevExpress.Utils.DefaultBoolean.True
ganttControl1.OptionsCustomization.AllowModifyDependencies = DevExpress.Utils.DefaultBoolean.True
When a user modifies a task, the control raises events. You can handle these events to customize the operation. For example, the TaskMoveCompleted event fires when a user finishes moving a task to a new time slot, and allows you to cancel the operation. The code below shows how to ask for confirmation when a user moves a task beyond the project bounds.
ganttControl1.TaskMoveCompleted += GanttControl1_TaskMoveCompleted;
private void GanttControl1_TaskMoveCompleted(object sender, TaskMovingEventArgs e) {
if (e.CurrentTaskStart < ganttControl1.Nodes[0].GetStartDate())
e.Cancel = XtraMessageBox.Show(String.Format("You moved '{0}' to start before the project starts. Do you want to proceed?", e.ProcessedTask.Text), "Planning Wizard", MessageBoxButtons.YesNo) != DialogResult.Yes;
if (e.CurrentTaskFinish > ganttControl1.Nodes[0].GetFinishDate())
e.Cancel = XtraMessageBox.Show(String.Format("You moved '{0}' to finish after the project finishes. Do you want to proceed?", e.ProcessedTask.Text), "Planning Wizard", MessageBoxButtons.YesNo) != DialogResult.Yes;
}
AddHandler ganttControl1.TaskMoveCompleted, AddressOf GanttControl1_TaskMoveCompleted
Private Sub GanttControl1_TaskMoveCompleted(ByVal sender As Object, ByVal e As TaskMovingEventArgs)
If e.CurrentTaskStart < ganttControl1.Nodes(0).GetStartDate() Then
e.Cancel = XtraMessageBox.Show(String.Format("You moved '{0}' to start before the project starts. Do you want to proceed?", e.ProcessedTask.Text), "Planning Wizard", MessageBoxButtons.YesNo) <> System.Windows.Forms.DialogResult.Yes
End If
If e.CurrentTaskFinish > ganttControl1.Nodes(0).GetFinishDate() Then
e.Cancel = XtraMessageBox.Show(String.Format("You moved '{0}' to finish after the project finishes. Do you want to proceed?", e.ProcessedTask.Text), "Planning Wizard", MessageBoxButtons.YesNo) <> System.Windows.Forms.DialogResult.Yes
End If
End Sub
See the following topic for more information: Interactive Editing.
To enable a modal form instead of cell editors, set the EditingMode property to EditForm. You can also customize the form layout or use a custom form.
ganttControl1.OptionsBehavior.EditingMode = DevExpress.XtraTreeList.TreeListEditingMode.EditForm;
ganttControl1.OptionsEditForm.FormCaptionFormat = "Summary Task Information - {Text}";
ganttControl1.Columns["StartDate"].OptionsEditForm.StartNewRow = true;
ganttControl1.Columns["Text"].OptionsEditForm.VisibleIndex = -2;
ganttControl1.Columns["Duration"].OptionsEditForm.VisibleIndex = -1;
ganttControl1.Columns["Text"].OptionsEditForm.UseEditorColRowSpan = false;
ganttControl1.Columns["Text"].OptionsEditForm.ColumnSpan = 2;
ganttControl1.Columns["Resources"].OptionsEditForm.UseEditorColRowSpan = false;
ganttControl1.Columns["Resources"].OptionsEditForm.ColumnSpan = 3;
ganttControl1.Columns["Resources"].OptionsEditForm.StartNewRow = true;
ganttControl1.OptionsBehavior.EditingMode = DevExpress.XtraTreeList.TreeListEditingMode.EditForm
ganttControl1.OptionsEditForm.FormCaptionFormat = "Summary Task Information - {Text}"
ganttControl1.Columns("StartDate").OptionsEditForm.StartNewRow = True
ganttControl1.Columns("Text").OptionsEditForm.VisibleIndex = -2
ganttControl1.Columns("Duration").OptionsEditForm.VisibleIndex = -1
ganttControl1.Columns("Text").OptionsEditForm.UseEditorColRowSpan = False
ganttControl1.Columns("Text").OptionsEditForm.ColumnSpan = 2
ganttControl1.Columns("Resources").OptionsEditForm.UseEditorColRowSpan = False
ganttControl1.Columns("Resources").OptionsEditForm.ColumnSpan = 3
ganttControl1.Columns("Resources").OptionsEditForm.StartNewRow = True
See the following topic for more information: Edit Form.
If the ScheduleMode property is set to Auto, the control automatically reschedules successor tasks when a user modifies a particular task. Set this property to Manual to disable automatic scheduling.
ganttControl1.OptionsBehavior.ScheduleMode = DevExpress.XtraGantt.Options.ScheduleMode.Auto;
ganttControl1.OptionsBehavior.ScheduleMode = DevExpress.XtraGantt.Options.ScheduleMode.Auto
The control takes the workweek schedule and holidays into account when it reschedules tasks. To specify the workweek schedule and holidays, click Run Designer in the control’s smart tag menu and switch to the Work Week Schedule section.
See the following topic for more information: Workweek Schedule and Exceptions.
The control gives you access to the drawing surface when a task is about to be drawn on-screen. You can draw a task or customize appearance settings. The code below shows how to customize the background color of tasks that missed a deadline.
DateTime deadLine = new DateTime(2020, 8, 26);
private void GanttControl1_CustomDrawTask(object sender, CustomDrawTaskEventArgs e) {
if (e.FinishDate > deadLine)
e.Info.Appearance.BackColor = Color.Red;
}
Private deadLine As New DateTime(2020, 8, 26)
Private Sub GanttControl1_CustomDrawTask(ByVal sender As Object, ByVal e As CustomDrawTaskEventArgs)
If e.FinishDate > deadLine Then
e.Info.Appearance.BackColor = Color.Red
End If
End Sub
See the following topic for more information and code samples: Tasks, Summaries, and Milestones.