Get started

Get and apply the software library to your project using the NuGet package.

The necessary DlhSoft.* assembly references (based on whether you are using .NET Framework or .NET Core) are automatically added to your application project in Visual Studio®. Reference the appropriate namespaces in code with xmlns attributes for the XAML root element and/or using clauses in code behind:

<Window …
        xmlns:hdc   = "clr-namespace:DlhSoft.Windows.Controls;assembly=DlhSoft.HierarchicalData.LightWPF.Controls"
        xmlns:pdgcc = "clr-namespace:DlhSoft.Windows.Controls;assembly=DlhSoft.ProjectData.GanttChart.LightWPF.Controls">


Add the required control instances as child nodes of appropriate XAML container elements or create component objects in code behind:

    <pdgcc:GanttChartDataGrid x:Name="GanttChartDataGrid" … />


Data items

To load and present data items within GanttChartDataGrid or other Gantt Chart based component instances initialize their Items collections (with a single setter or Add method calls). The item type to use depends on the actual component type. For Gantt Chart controls define GanttChartItem objects providing these properties:

  • Content values usually specify task names;
  • Start and Finish date and time values indicate the scheduled times of their displayed bars;
  • CompletedFinish date and time values specify the schedule times of their completion displayed bars (indicating completion percentages);
  • IsMilestone Boolean values determine the project milestones that are presented as diamond shapes in the chart;
  • AssignmentsContent values specify indicate the assigned resource names of each task, separated by commas;
  • Indentation values generate the hierarchical work breakdown structure of the project (summary and standard tasks).

var item1 = new GanttChartItem { Content = "My summary task" };
var item2 = new GanttChartItem { Content = "My standard task", Indentation = 1,
                                 Start = DateTime.Today, Finish = DateTime.Today.AddDays(5), CompletedFinish = DateTime.Today.AddDays(3),
                                 AssignmentsContent = "My resource" };
GanttChartDataGrid.Items = new ObservableCollection<GanttChartItem> { item1, item2 };
var item3 = new GanttChartItem { Content = "My milestone", Indentation = 1,
                                 IsMilestone = true };


To initialize dependencies between Gantt Chart bars, use the successor item’s Predecessors collection. The referred Item is determined by reference within the component’s Items collection. DependencyType enumeration supports all common types of task links:

item3.Predecessors.Add(new PredecessorItem { Item = item2, DependencyType = DependencyType.FinishFinish });


You may supplementary customize items using classic inheritance and new properties, if needed:

public class CustomGanttChartItem : GanttChartItem
    public string Description { get; set; }


    new CustomGanttChartItem { Content = "My task", Description = "My task’s description" });


To customize the displayed grid columns, use the Columns property of the component. To display hierarchical content use the DataTreeGridColumn object. You may also refer custom item properties from bindings and data templates:

        <hdc:DataTreeGridColumn   Header="Task"/>
        <d:DataGridTextColumn     Header="Start"   Binding="{Binding Start}">
        <d:DataGridTextColumn     Header="Finish"  Binding="{Binding Finish}">
        <d:DataGridTextColumn     Header="Details" Binding="{Binding Description}">
        <d:DataGridTemplateColumn Header="Details">
                <TextBox Text="{Binding Description}"/>


If needed (such as if you use an MVVM based approach), you may use our generic built-in item collection converters (or provide custom converter implementations instead) to bind Items collections directly to your business logic or data layers, referring the actual Member properties that the component should manage from your data items that can be referred as Tag objects of component items:

            <pdgcc:TaskItemsConverter ContentMember="Name" IndentationMember="IndentLevel"
                                      StartMember="StartDate" FinishMember="FinishDate" CompletedFinishMember="CompletionCurrentDate" 
                                      PredecessorsMember="Predecessors" PredecessorItemMember="Reference" PredecessorDependencyTypeMember="Type"
                                      UpdateTargetOnSourceChanges="True" UpdateSourceOnTargetChanges="True"/>


<d:DataGridTextColumn Header="Details" Binding="{Binding Tag.Description}">


Timeline definition

To specify the displayed timeline page and the zoom level of the chart:

GanttChartDataGrid.SetTimelinePage(start, finish);
GanttChartDataGrid.HourWidth = zoomLevel;


To specify the time schedule displayed and used by default by the control:

<pdgcc:GanttChartDataGrid …
    WorkingWeekStart="Monday"   WorkingWeekFinish="Friday"
    VisibleWeekStart="Sunday"   VisibleWeekFinish="Saturday"
    VisibleDayStart ="09:00:00" VisibleDayFinish ="17:00:00"/>


Alternatively, you can use Schedule objects, which are supported also at task item level:

GanttChartDataGrid.Schedule = new Schedule(workingWeekStart: DayOfWeek.Monday, workingWeekFinish: DayOfWeek.Friday …);
item.Schedule               = new Schedule(…);


To set up the scales displayed by the control use the Scales collection. The Scale objects define their type, header texts, and separator lines. By default Weeks scales are displayed as starting on Sunday; to display weeks starting on Monday instead, simply set ScaleType property to WeeksStartingMonday:

     <DataTemplate x:Key="ScaleHeaderContentTemplate">
         <ContentControl Content="{Binding}" HorizontalContentAlignment="Left" VerticalContentAlignment="Center" Margin="2" IsTabStop="False"/>


        <pdgcc:Scale ScaleType="Months" HeaderBorderBrush="Silver"
                     HeaderBorderThickness="0,0,1,1" HeaderContentTemplate="{StaticResource ScaleHeaderContentTemplate}"
                     BorderBrush="Silver" BorderThickness="0,0,1,0"/>
        <pdgcc:Scale ScaleType="WeeksStartingMonday" HeaderHeight="0" BorderBrush="Silver"
        <pdgcc:Scale ScaleType="Days" HeaderContentFormat="DayLeadingZero"
                     HeaderBorderBrush="Silver" HeaderBorderThickness="0,0,1,1"
                     HeaderContentTemplate="{StaticResource ScaleHeaderContentTemplate}"
                     BorderBrush="Silver" BorderThickness="0,0,0.15,0"/>
        <pdgcc:Scale ScaleType="Hours" HeaderBorderBrush="Silver"
                     HeaderBorderThickness="0,0,1,1" HeaderContentTemplate="{StaticResource ScaleHeaderContentTemplate}"/>



To configure the look of the Gantt Chart bars:

<pdgcc:GanttChartDataGrid …
       StandardBarFill            ="{StaticResource CustomBlueBarBrush}"
       StandardBarStroke          ="{StaticResource CustomBlueBorderBrush}"    StandardBarStrokeThickness          ="2"
       SummaryBarFill             ="{StaticResource CustomBlackPolygonBrush}"
       SummaryBarStroke           ="{StaticResource CustomBlackBorderBrush}"   SummaryBarStrokeThickness           ="1"
       MilestoneBarFill           ="{StaticResource CustomBlackDiamondBrush}"
       MilestoneBarStroke         ="{StaticResource CustomBlackBorderBrush}"   MilestoneBarStrokeThickness         ="1"
       StandardCompletedBarFill   ="{StaticResource CustomBlackBarBrush}"
       StandardCompletedBarStroke ="{StaticResource CustomBlackBorderBrush}"   StandardCompletedBarStrokeThickness ="1"
       DependencyLineStroke       ="{StaticResource CustomBlueLineBrush}"      DependencyLineStrokeThickness       ="1" />


You may also initialize individual item appearance settings using attached properties from code behind:

GanttChartView.SetStandardBarFill(item1, customGreenBarBrush);
GanttChartView.SetStandardBarFill(item2, customBrownBarBrush);
GanttChartDataGrid.AreIndividualItemAppearanceSettingsApplied = true;


Alternatively or supplementary, you can configure the bar, dependency line, and tool tip templates using XAML (see Bar templating sample source code):

<pdgcc:GanttChartDataGrid …
       StandardTaskTemplate       ="{StaticResource CustomStandardBarTemplate}"
       SummaryTaskTemplate        ="{StaticResource CustomSummaryPolygonTemplate}"
       MilestoneTaskTemplate      ="{StaticResource CustomMilestoneDiamondTemplate}"
       AssignmentsTemplate        ="{StaticResource CustomAssignmentsTemplate}"
       DependencyLineTemplate     ="{StaticResource CustomArrowTemplate}"
       ToolTipTemplate            ="{StaticResource CustomTaskDetailsTemplate}"
       PredecessorToolTipTemplate ="{StaticResource CustomPredecessorDetailsTemplate}"/>


More settings

To set up assignable resources and define their costs, and to set up resource schedules to use when they are assigned on task items without specific schedules (considering the first resource among the ones assigned with maximum allocation units):

GanttChartDataGrid.AssignableResources       = …; 
GanttChartDataGrid.ResourceQuantities        = …; 
GanttChartDataGrid.SpecificResourceHourCosts = …;
GanttChartDataGrid.ResourceSchedules         = …;


To further configure the look and feel, behavior, and other aspects of the components use their other member properties:

GanttChartDataGrid.IsAsyncPresentationEnabled = false; 
GanttChartDataGrid.IsUndoEnabled = true; 
GanttChartDataGrid.AreSummaryRowsBold = true; 
GanttChartDataGrid.AreTaskDependencyConstraintsEnabled = true;
GanttChartDataGrid.IsMouseWheelZoomEnabled = false; 
GanttChartDataGrid.AreUpdateTimelinePageButtonsVisible = false; 
GanttChartDataGrid.UpdateScaleInterval = TimeSpan.FromHours(1); 
GanttChartDataGrid.IsBaselineVisible = true;
GanttChartDataGrid.AlternatingItemBackground = alternatingRowBackgroundBrush; 
GanttChartDataGrid.IsChartSelectionHighlightingEnabled = true;


Hierarchical operations

To get the root or leaf tasks from the managed collection:

foreach (var root in GanttChartDataGrid.GetRoots())  { … }; 
foreach (var leaf in GanttChartDataGrid.GetLeaves()) { … };


To get the parent, or enumerate ascendants, children, or descendants of a specific task item:

var parent = GanttChartDataGrid.GetParent(item);
foreach (var ascendant  in GanttChartDataGrid.GetAllParents(item))  { … };
foreach (var child      in GanttChartDataGrid.GetChildren(item))    { … };
foreach (var descendant in GanttChartDataGrid.GetAllChildren(item)) { … };


Project management

To reschedule tasks so that project work is fully optimized or assigned resources are not over-allocated:



To enumerate critical tasks (those that by rescheduling might affect the finish date and time of the project):

foreach (var item in GanttChartDataGrid.GetCriticalItems()) { … };


Importing, exporting, and printing

To import or export project data from or to Microsoft® Project® XML files (an alternative ProjectXmlSerializer class is also available if you need advanced control during serialization and deserialization):



To send the Gantt Chart and associated data grid content to the printer (allowing the end user to select the printing settings), optionally rotating the output to generate landscape output by default (for WPF use the provided DocumentPaginator class to preconfigure all printing settings instead):

GanttChartDataGrid.Print("My document", rotate: true);


Handling events

You may run custom code upon specific item changes:

GanttChartDataGrid.ItemPropertyChanged   += (sender, e) { … };
GanttChartDataGrid.ItemCollectionChanged += (sender, e) { … };


Other types of changes also provide notifications:

GanttChartDataGrid.ItemActivated       += (sender, e) { … }; // Task bar clicked
GanttChartDataGrid.TimelinePageChanged += (sender, e) { … }; // Timeline page changed


More operations

To display the current items from a Gantt Chart control in different way using a Schedule Chart control, and eventually apply changes to the original component:

var scheduleChartItems = GanttChartDataGrid.GetScheduleChartItems();
ScheduleChartDataGrid.Items = scheduleChartItems;




Other member methods and events are available to provide advanced operations with the components and the data items they manage:

GanttChartDataGrid.Move(item, toIndex, includeChildren: false);
GanttChartDataGrid.MoveUp(item, includeChildren: true, withinParent: true);
GanttChartDataGrid.MoveDown(item, includeChildren: true, withinParent: true);
var projectCost = GanttChartDataGrid.GetProjectCost();
var finish      = GanttChartDataGrid.GetProjectFinish();