In the Q2 2013 SP1 release, we announced the beta version of a new control, RadGanttView. This control gives you the power to display project related tasks, milestones and dependencies in a visually appealing and fully interactive way. In this blog post, I will show you how easy this control is to use to visualize and manipulate project data.
The next thing we are going to need is some data for the GanttView to plot. We will “borrow” some of the data from the WinForms sample application by using the same XML data file. This data represents the tasks required to be completed when planning a wedding. Add the data file to your project and set its “Copy to Output Directory” property to “Copy if newer”. The data in the XML is made up of collections of two main Elements, they are Task and Link. A Task consists of an Id, to uniquely identify it, a ParentId to indicate if it is a child of another task, a Title as well as a Start and Stop date/time. A Link defines rules to impose on related tasks. For instance, if one task must be completed in order for the next one to start. To represent this, the Link element has a Start and End Id that represent the tasks, as well as link type. A link type is represented as an integer enumeration in C#, but in the data is represented as the integer value as follows:
0 | Finish to Finish |
1 | Finish to Start |
2 | Start to Finish |
3 | Start to Start |
Logical view of the XML elements:
Now we are ready to implement loading the data and displaying it in the GanttView. In the designer, double-click on Form1 to implement the Load event. In our example we will load the XML data directly into a DataSet. To do this, add the following code to the Load event of the form:
DataSet weddingPlan = new DataSet();
using (StreamReader rdr = new StreamReader("TelerikWeddingPlanner.xml"))
{
weddingPlan.ReadXml(rdr);
}
this.radGanttView1.DataSource = weddingPlan;
Next we need to provide the mapping of the internal fields of RadGanttView to the fields from our data (based on the Task and Link elements described above). To do this, add the following code to the Load event of the form:
this.radGanttView1.GanttViewElement.TaskDataMember = "Tasks";
this.radGanttView1.GanttViewElement.ChildMember = "Id";
this.radGanttView1.GanttViewElement.ParentMember = "ParentId";
this.radGanttView1.GanttViewElement.TitleMember = "Title";
this.radGanttView1.GanttViewElement.StartMember = "Start";
this.radGanttView1.GanttViewElement.EndMember = "Finish";
this.radGanttView1.GanttViewElement.ProgressMember = "Progress";
this.radGanttView1.GanttViewElement.LinkDataMember = "Links";
this.radGanttView1.GanttViewElement.LinkStartMember = "StartId";
this.radGanttView1.GanttViewElement.LinkEndMember = "EndId";
this.radGanttView1.GanttViewElement.LinkTypeMember = "LinkType";
Note that “Tasks” and “Links” are the names of the collections in our XML file. Now we will tell RadGanttView what columns we want to display. To do this, add the following code to the Load event:
this.radGanttView1.GanttViewElement.Columns.Add(new GanttViewTextViewColumn("Id"));
this.radGanttView1.GanttViewElement.Columns.Add(new GanttViewTextViewColumn("ParentId"));
this.radGanttView1.GanttViewElement.Columns.Add(new GanttViewTextViewColumn("Title"));
this.radGanttView1.GanttViewElement.Columns.Add(new GanttViewTextViewColumn("Start"));
this.radGanttView1.GanttViewElement.Columns.Add(new GanttViewTextViewColumn("Finish"));
this.radGanttView1.GanttViewElement.Columns[0].Visible = false;
this.radGanttView1.GanttViewElement.Columns[1].Visible = false;
this.radGanttView1.GanttViewElement.Columns[2].Width = 350;
this.radGanttView1.GanttViewElement.Columns[3].Width = 120;
this.radGanttView1.GanttViewElement.Columns[4].Width = 120;
The last thing that we want to do is to set the timeline displayed in RadGanttView to be more appropriate for the data being displayed. To do this append the following code to the Load event of the form:
this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineRange = TimeRange.Month;
this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineStart =
new DateTime(2006, 8, 21);
this.radGanttView1.GanttViewElement.GraphicalViewElement.TimelineEnd =
new DateTime(2007, 4, 3);
In order to add a task, we must handle the ItemChildIdNeeded event of the GanttView. Select the RadGanttView control in the designer, and in the properties pane, double-click on the ItemChildIdNeeded event. This event allows you to ensure that the unique naming of the ID value on new Tasks remains consistent with the data, and is non-generic. In our case we will handle this event with the following code:
int max = int.MinValue;
foreach (DataRow row in (this.radGanttView1.DataSource as DataSet).Tables[0].Rows)
{
if (int.Parse(row[0].ToString()) > max)
{
max = int.Parse(row[0].ToString());
}
}
e.ChildId = ++max;
Now when we run the application, you can add tasks by using the context menu.
From this blog post it’s easy to see that RadGanttView is both a stunning and functional control. I urge you to take this control out for a spin and provide us your feedback. I’m sure you’ll agree that this control makes a great addition to the RadControls for WinForms suite.
Carey Payette is a Senior Software Engineer with Trillium Innovations (a Solliance partner), an ASPInsider, a Progress Ninja, a Microsoft Certified Trainer and a Microsoft Azure MVP. Her primary focus is cloud integration and deployment for the web, mobile, big data, AI, machine learning and IoT spaces. Always eager to learn, she regularly tinkers with various sensors, microcontrollers, programming languages and frameworks. Carey is also a wife and mom to three fabulous boys.