10318 : How do I serialize a Gantt chart?

Question

How do I serialize a Gantt chart? Do GTP.NET customers roll their own file formats for saving Gantt charts or do you offer something with your product?

 

Answer

Since the Gantt and Grid can be used with datasource and databind we incourage user to hold their data in datasets. The datasets can be persisted as xml or in a database.

This info is from the latest help file; it describes databinding as it is set up in the Gantt_Database sample.

Gantt_Database sample

The sample Gantt_Database shows how to connect the Gantt to a database that has one table for hierarcical grid nodes (project) and one table for time items on these nodes (projects).

 images has been removed (look in the help file for the complete story)

The timeitem table has a foreign key that links to its owning project (TimeItem.ownedby). And the projects has a foreign key that is set to the project parent if it exists. If it does not exists we set this foreign key to -1 or to null.

In the load button of the sample we use the sqladapters to fill the datasets. We create a dataview on the project dataset that filters out the project rows with no parent (firstView.RowFilter="ISNULL(ownedby,-1)=-1";)

We bind the rootnodes of the grid to this dataview with this call: gantt1.GridProperties.RootNodes_DataSourceList=firstView;


		private void button1_Click(object sender, System.EventArgs e)
		{
			dataSet21.Clear();
			dataSet21.project.Clear();
			sqlDataAdapter1.Fill(dataSet21);
			DataView firstView = new DataView(dataSet21.project);
			firstView.RowFilter="ISNULL(ownedby,-1)=-1";
			gantt1.GridProperties.RootNodes_DataSourceList=firstView;

			dataSet_timeitems1.Clear();
			sqlDataAdapter2.Fill(dataSet_timeitems1);

		}
Now the root-nodes will be created from all the rows in the dataview.
The Grid cell values will be resolved using the DataSourceColumn field in the GridColumn (Gantt.GridProperties.Columns):

 images has been removed (look in the help file for the complete story)

For each GridNode that is created we want to check if there should be any sub-nodes and/or time items.
We do this in the event OnNodeInserted:

		private void gantt1_OnNodeInserted(PlexityHide.GTP.Grid aGrid, PlexityHide.GTP.NodeEventArgs e)
		{
		
			object row=e.GridNode.ListItemWhenDataBound();
			object val=e.GridNode.OwningCollection.NodeDataConnect.CurrencyManager.GetItemProperties().Find("id",true).GetValue(row);

			// Set up tree using DataViews, in this sample we only allow for SubLevel zero (root nodes) to have sub nodes
			if (e.GridNode.SubLevel==0)
			{
				DataView subNodeView = new DataView(dataSet21.project);
				if (val is Int32)
					subNodeView.RowFilter="ownedby="+val.ToString();
				else
					subNodeView.RowFilter="ownedby=-1";
			  // Set the SubNodes to bind to the subNodeView
				e.GridNode.SubNodes_DataSourceList=subNodeView;
			}

			// Set up time items in layer 0 with a dataview of the time items dataset
			GanttRow gr=Gantt.GanttRowFromGridNode(e.GridNode);
			DataView timeitemView = new DataView(dataSet_timeitems1.timeitem);
			if (val is Int32)
				timeitemView.RowFilter="ownedby="+val.ToString();
			else
				timeitemView.RowFilter="ownedby=-1";
			gr.Layers[0].NameInDS_Start="start";
			gr.Layers[0].NameInDS_Stop="stop";
			gr.Layers[0].DataSourceList=timeitemView;
			gr.Layers[0].TimeItemLayout="NiceLook";


		}
And that is it. When you change the time items start or stop properties the dataset will be updated. 
When you change the grid cells the dataset will be updated.

But what about moving a time item to a different row?

To handle the move, we actually only want to assign a different foreign key to the TimeItem row in the TimeItem table, 
this has very little to do with the gantt control itself, but we need to react to this operation:

    private void gantt1_OnTimeItem_ChangeRow(PlexityHide.GTP.Gantt aGantt, PlexityHide.GTP.TimeItemEventArgs e)
    {
      // What we really want to do when changing rows in a databound Gantt is to change the data in the dataset to reflect 
      // the change of owner. This change in data will propagte into the Gantt Automatically.
      
      e.Allow=false; // Do not perform the move, let propagation handle it 
      
      DataRowView row=e.TimeItem.ListItemWhenDataBound() as DataRowView;
      DataRowView noderow=e.NewGanttRow.GridNode.ListItemWhenDataBound() as DataRowView;

      row["ownedby"]=noderow["id"];   // Set the OwnedBy value to the id of the new row -> move it   
    }

Leave a Reply