DayPilot 甘特图 for ASP.NET






4.85/5 (21投票s)
如何在 ASP.NET 应用程序中显示 AJAX 甘特图。
- 下载示例项目 (C#, VB) - Visual Studio 2010, DayPilot Lite 3.2 - 636 kB [codeproject.com]
- 下载示例项目 (C#, VB) - Visual Studio 2012, DayPilot Lite 4.1 - 734 kB [codeproject.com]
- 下载示例项目 (C#, VB) - Visual Studio 2013, DayPilot Lite 5.0 - 913 kB [codeproject.com]
- 下载示例项目 (C#, VB) - Visual Studio 2015, DayPilot Lite 5.0 SP2 - 921 kB [codeproject.com]
- 下载 DayPilot [daypilot.org]
- 在线演示 [daypilot.org]
DayPilot Scheduler 是一个灵活的开源 ASP.NET 控件,用于显示多个资源的事件(Apache 软件许可证 2.0)。
相关文章
- DayPilot Scheduler 控件 for ASP.NET [codeproject.com]
通过新的 DayPilot 3.2 版本,可以显示一个 **甘特图** (ViewType="Gantt")。在甘特图模式下,会为 DataSource 中的每个任务创建一个特殊行。
本文展示了如何使用 DayPilot Scheduler 显示甘特图,并通过 AJAX 模态对话框处理基本的任务操作(创建、编辑)。示例 ASP.NET 应用程序将任务数据存储在 SQL Server 数据库中。Visual Studio 解决方案包含 C# 和 Visual Basic 两种语言的源代码。
特点
- 每行显示一个任务(甘特图)
- 数据存储在 **SQL Server 数据库**中(需要 SQL Server 2008 Express 或更高版本)
- 在自定义 **列**中显示附加数据(任务持续时间)
- 可以通过拖放操作 **调整** 标题列的大小
- 使用 **UpdatePanel** 快速刷新
- 使用 **模态对话框** 创建和编辑事件
甘特图模式与资源模式对比
在 **甘特图视图** 中,会自动为每个事件/任务创建一个特殊行。
与 Scheduler 的 资源视图 进行比较,在资源视图中,行是手动定义的(使用 Resources 属性),并且可以将多个事件分配给同一资源。
资源

甘特图

| 行为 | ViewType="Gantt" | ViewType="Resources" | 
|---|---|---|
| Rows | 自动生成,每个事件一行 | 使用 Resources 集合手动定义 | 
| 行内有多个并发事件 | 不允许 | 允许 | 
| 行自定义(BeforeResHeaderRender 事件) | 是 | 是 | 
| 事件自定义(BeforeEventRender 事件) | 是 | 是 | 
| 自定义行标题列 | 是 | 是 | 
| 需要 DataResourceField | 否 | 是 | 
加载任务到甘特图

加载任务只需设置 DataSource 及其字段(DataStartField, DataEndField, DataTextField, DataValueField)和 ViewType。
Default.aspx
<DayPilot:DayPilotScheduler ID="DayPilotScheduler1" runat="server" ViewType="Gantt" />
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
  if (!IsPostBack)
  {
    LoadEvents();
  }
}
private void LoadEvents()
{
  DayPilotScheduler1.DataStartField = "AssignmentStart";
  DayPilotScheduler1.DataEndField = "AssignmentEnd";
  DayPilotScheduler1.DataTextField = "AssignmentNote";
  DayPilotScheduler1.DataValueField = "AssignmentId";
  DayPilotScheduler1.DataSource = new DataManager().GetAssignments();
  DataBind();
}
DataManager 是一个数据访问的辅助类。GetAssigments() 方法用于加载任务
 public DataTable GetAssignments()
{
  DataTable dt = new DataTable();
  var da = CreateDataAdapter("select * from [Assignment]");
  da.Fill(dt);
  return dt;
} 
定义甘特图标题列

您可以修改 **HeaderColumns** 属性来定制列(任务、持续时间)。
为要显示的每一列设置 **Title** 和 **Width** 属性。
Default.aspx
<DayPilot:DayPilotScheduler 
  ID="DayPilotScheduler1" 
  runat="server" 
  ViewType="Gantt">
    <HeaderColumns>
      <DayPilot:RowHeaderColumn title="Task" Width="150" />
      <DayPilot:RowHeaderColumn title="Duration" Width="80" />
    </HeaderColumns>
</DayPilot:DayPilotScheduler>
将任务数据加载到列中

行标题可以使用 **BeforeResHeaderRender** 事件处理程序进行自定义。在甘特图模式下,此事件会为每个任务调用一次。
您可以调整默认列(e.InnerHTML)和附加自定义列(e.Columns 集合)的 HTML。
protected void DayPilotScheduler1_BeforeResHeaderRender(object sender, BeforeHeaderRenderEventArgs e)
{
  DataItemWrapper task = e.DataItem;
  int duration = Convert.ToInt32(task["AssignmentDuration"]);
  e.Columns[0].InnerHTML = "<div style='text-align:right; padding: 0px 6px 0px 2px;'>" + duration + " days</div>";
}
持久化列宽

可以通过拖动分隔线来调整标题列的大小。用户完成调整后,服务器端会触发 **HeaderColumnWidthChanged** 事件。
页面加载时,检查保存的列宽
 protected void Page_Load(object sender, EventArgs e)
{
  // ...
  string cols = new DataManager().GetUserConfig(User.Identity.Name, "project.cols");
  if (cols != null)
  {
    DayPilotScheduler1.RowHeaderColumnWidths = cols;
  }
}
每当用户更改列宽时,将新的宽度保存到数据库。
 protected void DayPilotScheduler1_HeaderColumnWidthChanged(object sender, HeaderColumnWidthChangedEventArgs e)
{
  new DataManager().SetUserConfig(User.Identity.Name, "project.cols", DayPilotScheduler1.RowHeaderColumnWidths);
  LoadEvents();
}
在模态对话框中编辑事件

“新建任务”使用 DayPilot.Modal 脚本在模态对话框中打开 New.aspx 页面。
<div><a href="javascript:create('<%# DateTime.Today.ToString("s") %>')">New Task</a></div>
<script type="text/javascript">
  function create(start) {
    createModal().showUrl('New.aspx?start=' + start);
  }
function createModal() {
  var modal = new DayPilot.Modal();
  modal.border = "10px solid #d0d0d0";
  modal.closed = function () {
    if (this.result && this.result.refresh) {
      __doPostBack(id.refreshButton, '');
    }
  };
  return modal;
}
</script>
New.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="New.aspx.cs" Inherits="Project_New" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>New</title>
  <link href="~/Media/layout.css" rel="stylesheet" type="text/css" />
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <table border="0" cellspacing="4" cellpadding="0">
      <tr>
      <td align="right" valign="top"></td>
      <td><h1>New Task</h1></td>
      </tr>
      <tr>
      <td align="right">Start:</td>
      <td><asp:TextBox ID="TextBoxStart" runat="server"></asp:TextBox></td>
      </tr>
      <tr>
      <td align="right">Duration:</td>
      <td><asp:DropDownList ID="DropDownListDuration" runat="server">
      <asp:ListItem>1</asp:ListItem>
      <asp:ListItem>2</asp:ListItem>
      <asp:ListItem>3</asp:ListItem>
      <asp:ListItem>4</asp:ListItem>
      <asp:ListItem>5</asp:ListItem>
      </asp:DropDownList>
      days</td>
      </tr>
      <tr>
      <td align="right">Description:</td>
      <td><asp:TextBox ID="TextBoxNote" runat="server"></asp:TextBox></td>
      </tr>
      <tr>
      <td align="right"></td>
      <td>
      <asp:Button ID="ButtonOK" runat="server" OnClick="ButtonOK_Click" Text="OK" />
      <asp:Button ID="ButtonCancel" runat="server" Text="Cancel" OnClick="ButtonCancel_Click" />
      </td>
      </tr>
    </table>
  </div>
  </form>
  <script type="text/javascript">
  document.getElementById("TextBoxNote").focus();
  </script>
</body>
</html> 
New.aspx.cs
public partial class Project_New : Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    if (!IsPostBack)
    {
      DateTime start = Convert.ToDateTime(Request.QueryString["start"]);
      TextBoxStart.Text = start.ToShortDateString();
    }
  }
  protected void ButtonOK_Click(object sender, EventArgs e)
  {
    DateTime start = Convert.ToDateTime(TextBoxStart.Text);
    int duration = Convert.ToInt32(DropDownListDuration.SelectedValue);
    string note = TextBoxNote.Text;
    new DataManager().CreateAssignment(start, duration, note);
    // passed to the modal dialog close handler, see Scripts/App/gantt.js
    Hashtable ht = new Hashtable();
    ht["refresh"] = "yes";
    ht["message"] = "Event created.";
    Modal.Close(this, ht);
  }
  protected void ButtonCancel_Click(object sender, EventArgs e)
  {
    Modal.Close(this);
  }
}
历史
- 2016 年 3 月 21 日 - 已添加 Visual Studio 2015 解决方案(SQL Server 2014, DayPilot Lite 5.0 SP2, DayPilot Modal 2.4, HTML5 doctype)
- 2015 年 5 月 15 日 - 已添加 Visual Studio 2013 解决方案(SQL Server 2014, DayPilot Lite 5.0)
- 2014 年 4 月 3 日 - "1 days" 的持续时间已修复为 "1 day"
- 2014 年 4 月 2 日 - Visual Studio 2012 解决方案已更新为 DayPilot Lite 4.1
- 2013 年 11 月 13 日 - 更新了适用于 Visual Studio 2012、LocalDB、DayPilot Lite 4.0、Windows 8 CSS 主题的版本
另请参阅
- DayPilot [daypilot.org]
- ASP.NET 开源甘特图 (C#, VB.NET) [code.daypilot.org]
 一个关于使用甘特图的基础分步教程。
- ASP.NET 项目管理(开源) [code.daypilot.org]
 在 ASP.NET 应用程序中使用甘特图的更复杂示例。



