As shown in the examples I have implemented a Provider for the Gantt chart. The provider appears to be working, when I break through it the methods are called, items are inserted, updated and deleted in the database etc. Both GetTasks and GetDependencies return an ITask list. The problem I'm having is that nothing appears in the Gantt chart (it loads with no Tasks showing).
When I add new Tasks those will show (and are added to the database) and I can update them etc. After a page refresh they also no longer show.
Here is the provider implementation, GetById returns a DataSet and Mutate returns an object containing the ID of inserted item + success/error info:
public class GanttCustomProvider : GanttProviderBase { private long _projectId; private string _connString; public GanttCustomProvider(long projectId, string connString) : base() { _projectId = projectId; _connString = connString; } public override ITaskFactory TaskFactory { get { return new CustomGanttTaskFactory(); } } public override List<ITask> GetTasks() { using (var client = new FunctionsClient()) { var source = client.GetById(new Phase { PROJECT_ID = _projectId, ConnectionString = _connString }) .Tables[0].AsEnumerable(); var list = source.Select(row => new CustomTask { ID = row["ID"], ParentID = row["PARENT"], Title = row["TITLE"].ToString(), Start = (DateTime)row["START_DATE"], End = (DateTime)row["END_DATE"], Summary = (bool)row["SUMMERY"], OrderID = row["ORDER_ID"], Expanded = (bool)row["EXPANDED"], PercentComplete = Decimal.Parse(row["PERCENTCOMPLETE"].ToString()), Time = (double)row["TIME"] }).ToList<ITask>(); return list; } } public override ITask InsertTask(ITask t) { var task = (CustomTask)t; using (var client = new FunctionsClient()) { task.ID = client.Mutate(new Phase { PROJECT_ID = _projectId, PARENT = (int?)task.ParentID, TITLE = task.Title, START_DATE = task.Start, END_DATE = task.End, SUMMERY = task.Summary, ORDER_ID = (int?)task.OrderID, EXPANDED = task.Expanded, Mode = Modes.Insert, ConnectionString = _connString }).returnID; return task; } } public override ITask UpdateTask(ITask t) { var task = (CustomTask)t; using(var client = new FunctionsClient()) { client.Mutate(new Phase { ID = (int)task.ID, PARENT = (int?)task.ParentID, PROJECT_ID = _projectId, TITLE = task.Title, START_DATE = task.Start, END_DATE = task.End, SUMMERY = task.Summary, ORDER_ID = (int)task.OrderID, EXPANDED = task.Expanded, TIME = task.Time, Mode = Modes.Update, ConnectionString = _connString }); } return task; } public override ITask DeleteTask(ITask task) { using (var client = new FunctionsClient()) { client.Mutate(new Phase { ID = (int)task.ID, Mode = Modes.Delete, ConnectionString = _connString }); return task; } } public override List<IDependency> GetDependencies() { using (var client = new FunctionsClient()) { var source = client.GetById(new PhaseDependency { ProjectID = _projectId, ConnectionString = _connString }) .Tables[0].AsEnumerable(); var list = source.Select(row => new Dependency { ID = row["ID"], PredecessorID = row["PredecessorID"], SuccessorID = row["SuccessorID"], Type = (DependencyType)row["Type"] }).ToList<IDependency>(); return list; } } public override IDependency InsertDependency(IDependency dependency) { using (var client = new FunctionsClient()) { dependency.ID = client.Mutate(new PhaseDependency { PredecessorID = (int)dependency.PredecessorID, SuccessorID = (int)dependency.SuccessorID, Type = (int)dependency.Type, Mode = Modes.Insert, ConnectionString = _connString }).returnID; } return dependency; } public override IDependency DeleteDependency(IDependency dependency) { using(var client = new FunctionsClient()) { client.Mutate(new PhaseDependency { ID = (int)dependency.ID, Mode = Modes.Delete, ConnectionString = _connString }); } return dependency; }}Here are the implementations of the Custom Task and Factory:
public class CustomTask : Task { public CustomTask() : base() { } public double? Time { get { return (double?)(ViewState["Time"] ?? (double?)null); } set { ViewState["Time"] = value; } } protected override IDictionary<string, object> GetSerializationData() { var dict = base.GetSerializationData(); dict["Time"] = Time; return dict; } public override void LoadFromDictionary(System.Collections.IDictionary values) { base.LoadFromDictionary(values); Time = values["Time"] == null ? (float?)null : float.Parse(values["Time"].ToString()); } } public class CustomGanttTaskFactory : ITaskFactory { Task ITaskFactory.CreateTask() { return new CustomTask(); } }
And finally the Page the Gantt is on:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GanttTest.aspx.cs" Inherits="GanttTest" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<telerik:RadScriptManager runat="server" />
<telerik:RadGantt runat="server" id="rgPlanning" AutoGenerateColumns="false" >
<YearView UserSelectable="True" />
<Columns>
<telerik:GanttBoundColumn DataField="Title" DataType="String" Width="100px" HeaderText="Title"/>
<telerik:GanttBoundColumn DataField="Start" DataType="DateTime" DataFormatString="dd/MM/yy" Width="100px" HeaderText="Start"/>
<telerik:GanttBoundColumn DataField="End" DataType="DateTime" DataFormatString="dd/MM/yy" Width="100px" HeaderText="End"/>
<telerik:GanttBoundColumn DataField="Time" DataType="Number" Width="100px" UniqueName="Time" HeaderText="Hours"/>
</Columns>
<CustomTaskFields>
<telerik:GanttCustomField PropertyName="Time" Type="Number" ClientPropertyName="time"/>
</CustomTaskFields>
</telerik:RadGantt>
</div>
</form>
</body>
</html>
And code behind:
public partial class GanttTest : Page { private long? projectID = 3; private string connString = "Connectionstring"; protected void Page_Load(object sender, EventArgs e) { rgPlanning.Provider = new GanttCustomProvider(projectID.Value, connString); } }