New to Telerik UI for WinForms? Download free 30-day trial

Custom Data Items

The data items displayed in RadGanttView have a predefined set of properties allowing each of the items to have defined Start, End, and Title values. In certain cases, one may need to display an additional column in the Gantt control and map this column to a custom field defined in the data item class. This can be easily achieved by extending the GanttViewDataItem class with additional properties.

The new properties added to an inherited GanttViewDataItem class must have property setters.

The example in this article will handle a scenario of a Duration column displaying how many days each of the tasks takes.

Figure 1: Custom Data Item

WinForms RadGanttView Custom Data Item

Setup the Control and Add Data

public GanttDataItemForm()
{
    InitializeComponent();
    this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineStart = new DateTime(2010, 10, 9);
    this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineEnd = new DateTime(2010, 10, 19);
    //setup data items
    MyGanttViewDataItem item1 = new MyGanttViewDataItem();
    item1.Start = new DateTime(2010, 10, 10);
    item1.End = new DateTime(2010, 10, 15);
    item1.Progress = 30m;
    item1.Title = "Summary task.1. title";
    MyGanttViewDataItem subitem11 = new MyGanttViewDataItem();
    subitem11.Start = new DateTime(2010, 10, 10);
    subitem11.End = new DateTime(2010, 10, 12);
    subitem11.Progress = 10m;
    subitem11.Title = "Sub-task.1.1 title";
    MyGanttViewDataItem subitem12 = new MyGanttViewDataItem();
    subitem12.Start = new DateTime(2010, 10, 12);
    subitem12.End = new DateTime(2010, 10, 15);
    subitem12.Progress = 20m;
    subitem12.Title = "Sub-task.1.2 title";
    //add subitems
    item1.Items.Add(subitem11);
    item1.Items.Add(subitem12);
    this.radGanttView1.Items.Add(item1);
    MyGanttViewDataItem item2 = new MyGanttViewDataItem();
    item2.Start = new DateTime(2010, 10, 12);
    item2.End = new DateTime(2010, 10, 18);
    item2.Progress = 40m;
    item2.Title = "Summary task.2. title";
    MyGanttViewDataItem subitem21 = new MyGanttViewDataItem();
    subitem21.Start = new DateTime(2010, 10, 12);
    subitem21.End = new DateTime(2010, 10, 13);
    subitem21.Progress = 10m;
    subitem21.Title = "Sub-task.2.1 title";
    MyGanttViewDataItem subitem22 = new MyGanttViewDataItem();
    subitem22.Start = new DateTime(2010, 10, 13);
    subitem22.End = new DateTime(2010, 10, 18);
    subitem22.Progress = 30m;
    subitem22.Title = "Sub-task.2.2 title";
    MyGanttViewDataItem subitem23 = new MyGanttViewDataItem();
    subitem23.Start = new DateTime(2010, 10, 18);
    subitem23.End = new DateTime(2010, 10, 18);
    subitem23.Title = "Sub-task.2.3 title";
    //add subitems
    item2.Items.Add(subitem21);
    item2.Items.Add(subitem22);
    item2.Items.Add(subitem23);
    this.radGanttView1.Items.Add(item2);
    //add links between items
    GanttViewLinkDataItem link1 = new GanttViewLinkDataItem();
    link1.StartItem = subitem11;
    link1.EndItem = subitem12;
    link1.LinkType = TasksLinkType.FinishToStart;
    this.radGanttView1.Links.Add(link1);
    GanttViewLinkDataItem link2 = new GanttViewLinkDataItem();
    link2.StartItem = subitem21;
    link2.EndItem = subitem22;
    link2.LinkType = TasksLinkType.StartToStart;
    this.radGanttView1.Links.Add(link2);
    GanttViewLinkDataItem link3 = new GanttViewLinkDataItem();
    link3.StartItem = subitem22;
    link3.EndItem = subitem23;
    link3.LinkType = TasksLinkType.FinishToStart;
    this.radGanttView1.Links.Add(link3);
    GanttViewTextViewColumn titleColumn = new GanttViewTextViewColumn("Title");
    GanttViewTextViewColumn startColumn = new GanttViewTextViewColumn("Start");
    GanttViewTextViewColumn endColumn = new GanttViewTextViewColumn("End");
    GanttViewTextViewColumn durationColumn = new GanttViewTextViewColumn("Duration");
    this.radGanttView1.GanttViewElement.Columns.Add(titleColumn);
    this.radGanttView1.GanttViewElement.Columns.Add(startColumn);
    this.radGanttView1.GanttViewElement.Columns.Add(endColumn);
    this.radGanttView1.GanttViewElement.Columns.Add(durationColumn);
    this.radGanttView1.GanttViewElement.EditorInitialized += GanttViewElement_EditorInitialized;
}

Public Sub New()
    InitializeComponent()
    Me.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineStart = New DateTime(2010, 10, 9)
    Me.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineEnd = New DateTime(2010, 10, 19)
    Dim item1 As MyGanttViewDataItem = New MyGanttViewDataItem()
    item1.Start = New DateTime(2010, 10, 10)
    item1.[End] = New DateTime(2010, 10, 15)
    item1.Progress = 30D
    item1.Title = "Summary task.1. title"
    Dim subitem11 As MyGanttViewDataItem = New MyGanttViewDataItem()
    subitem11.Start = New DateTime(2010, 10, 10)
    subitem11.[End] = New DateTime(2010, 10, 12)
    subitem11.Progress = 10D
    subitem11.Title = "Sub-task.1.1 title"
    Dim subitem12 As MyGanttViewDataItem = New MyGanttViewDataItem()
    subitem12.Start = New DateTime(2010, 10, 12)
    subitem12.[End] = New DateTime(2010, 10, 15)
    subitem12.Progress = 20D
    subitem12.Title = "Sub-task.1.2 title"
    item1.Items.Add(subitem11)
    item1.Items.Add(subitem12)
    Me.radGanttView1.Items.Add(item1)
    Dim item2 As MyGanttViewDataItem = New MyGanttViewDataItem()
    item2.Start = New DateTime(2010, 10, 12)
    item2.[End] = New DateTime(2010, 10, 18)
    item2.Progress = 40D
    item2.Title = "Summary task.2. title"
    Dim subitem21 As MyGanttViewDataItem = New MyGanttViewDataItem()
    subitem21.Start = New DateTime(2010, 10, 12)
    subitem21.[End] = New DateTime(2010, 10, 13)
    subitem21.Progress = 10D
    subitem21.Title = "Sub-task.2.1 title"
    Dim subitem22 As MyGanttViewDataItem = New MyGanttViewDataItem()
    subitem22.Start = New DateTime(2010, 10, 13)
    subitem22.[End] = New DateTime(2010, 10, 18)
    subitem22.Progress = 30D
    subitem22.Title = "Sub-task.2.2 title"
    Dim subitem23 As MyGanttViewDataItem = New MyGanttViewDataItem()
    subitem23.Start = New DateTime(2010, 10, 18)
    subitem23.[End] = New DateTime(2010, 10, 18)
    subitem23.Title = "Sub-task.2.3 title"
    item2.Items.Add(subitem21)
    item2.Items.Add(subitem22)
    item2.Items.Add(subitem23)
    Me.radGanttView1.Items.Add(item2)
    Dim link1 As GanttViewLinkDataItem = New GanttViewLinkDataItem()
    link1.StartItem = subitem11
    link1.EndItem = subitem12
    link1.LinkType = TasksLinkType.FinishToStart
    Me.radGanttView1.Links.Add(link1)
    Dim link2 As GanttViewLinkDataItem = New GanttViewLinkDataItem()
    link2.StartItem = subitem21
    link2.EndItem = subitem22
    link2.LinkType = TasksLinkType.StartToStart
    Me.radGanttView1.Links.Add(link2)
    Dim link3 As GanttViewLinkDataItem = New GanttViewLinkDataItem()
    link3.StartItem = subitem22
    link3.EndItem = subitem23
    link3.LinkType = TasksLinkType.FinishToStart
    Me.radGanttView1.Links.Add(link3)
    Dim titleColumn As GanttViewTextViewColumn = New GanttViewTextViewColumn("Title")
    Dim startColumn As GanttViewTextViewColumn = New GanttViewTextViewColumn("Start")
    Dim endColumn As GanttViewTextViewColumn = New GanttViewTextViewColumn("End")
    Dim durationColumn As GanttViewTextViewColumn = New GanttViewTextViewColumn("Duration")
    Me.radGanttView1.GanttViewElement.Columns.Add(titleColumn)
    Me.radGanttView1.GanttViewElement.Columns.Add(startColumn)
    Me.radGanttView1.GanttViewElement.Columns.Add(endColumn)
    Me.radGanttView1.GanttViewElement.Columns.Add(durationColumn)
    AddHandler Me.radGanttView1.GanttViewElement.EditorInitialized, AddressOf GanttViewElement_EditorInitialized
End Sub

Our implementation of the custom GanttViewDataItem class will add an integer Duration property. This property will be calculated whenever the Start or the End of a task changes.

Custom Data Item Implementation

public class MyGanttViewDataItem : GanttViewDataItem
{
    private int duration;
    private bool shouldUpdate;
    public MyGanttViewDataItem()
    { }
    public int Duration
    {
        get
        {
            return this.duration;
        }
        private set
        {
            if (this.duration != value)
            {
                this.duration = value;
                this.OnNotifyPropertyChanged("Duration");
            }
        }
    }

    protected override void OnNotifyPropertyChanged(string propertyName)
    {
        base.OnNotifyPropertyChanged(propertyName);
        if (propertyName == "Duration" && this.shouldUpdate)
        {
            TimeSpan span = this.End - this.End.Date;
            this.End = this.Start.AddDays(this.Duration).Add(span);
        }
        if (propertyName == "Start" || propertyName == "End")
        {
            this.shouldUpdate = false;
            this.Duration = (this.End - this.Start).Days;
        }
        this.shouldUpdate = true;
    }
}

Public Class MyGanttViewDataItem
    Inherits GanttViewDataItem
    Private _duration As Integer
    Private shouldUpdate As Boolean
    Public Sub New()
    End Sub
    Public Property Duration As Integer
        Get
            Return Me._duration
        End Get
        Private Set(ByVal value As Integer)
            If Me._duration <> value Then
                Me._duration = value
                Me.OnNotifyPropertyChanged("Duration")
            End If
        End Set
    End Property
    Protected Overrides Sub OnNotifyPropertyChanged(ByVal propertyName As String)
        MyBase.OnNotifyPropertyChanged(propertyName)
        If propertyName = "Duration" AndAlso Me.shouldUpdate Then
            Dim span As TimeSpan = Me.[End] - Me.[End].Date
            Me.[End] = Me.Start.AddDays(Me.Duration).Add(span)
        End If
        If propertyName = "Start" OrElse propertyName = "End" Then
            Me.shouldUpdate = False
            Me.Duration = (Me.[End] - Me.Start).Days
        End If
        Me.shouldUpdate = True
    End Sub
End Class

The Duration column will be working with a GanttViewSpinEditor and considering our scenario, we will need to change the MaxValue property of the editor. This can be accomplished by handling the RadGanttView.GanttViewElement.EditorInitialized event.

Handling the EditorInitialized event

private void GanttViewElement_EditorInitialized(object sender, GanttViewItemEditorInitializedEventArgs e)
{
    GanttViewSpinEditor editor = e.Editor as GanttViewSpinEditor;
    decimal totalDays = (decimal)(this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineEnd - this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineStart).TotalDays;
    if (editor != null && editor.MaxValue != totalDays)
    {
        editor.MaxValue = totalDays;
    }
}

Private Sub GanttViewElement_EditorInitialized(ByVal sender As Object, ByVal e As GanttViewItemEditorInitializedEventArgs)
    Dim editor As GanttViewSpinEditor = TryCast(e.Editor, GanttViewSpinEditor)
    Dim totalDays As Decimal = CDec((Me.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineEnd - Me.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineStart).TotalDays)
    If editor IsNot Nothing AndAlso editor.MaxValue <> totalDays Then
        editor.MaxValue = totalDays
    End If
End Sub

See Also

In this article