Sample Project
The sample project includes:
C# Source Code
SQL Server database
Visual Studio 2019 Solution
Features
Three shifts per day (7am - 3pm, 3pm - 11pm, 11pm - 7am)
Time headers grouped by day and month
Highlighting weekend shifts
Displaying nurses on the vertical (Y) axis
Displaying the timeline on the horizontal (X) axis
SQL Server database
See also an ASP.NET Core tutorial that implements shift scheduling for multiple locations/positions:
License
Licensed for testing and evaluation purposes. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for ASP.NET WebForms.
How to initialize the shift Scheduler control?
The first step is to add the <DayPilotScheduler>
tag to your ASP.NET WebForm page. The ASP.NET scheduler control lets you create the shift overview and provide the UI necessary for planning the nurse shifts.
<DayPilot:DayPilotScheduler
ID="DayPilotScheduler1"
runat="server"
/>
How to load nurse data?
We will use the Resources
property of the ASP.NET scheduler to display the nurses in Scheduler rows.
The nurses will be displayed on the vertical axis.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// ...
LoadResources();
// ...
}
}
private void LoadResources()
{
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM [resource] ORDER BY [resource_name]", ConfigurationManager.ConnectionStrings["daypilot"].ConnectionString);
DataTable dt = new DataTable();
da.Fill(dt);
DayPilotScheduler1.Resources.Clear();
foreach(DataRow dr in dt.Rows)
{
string name = (string) dr["resource_name"];
string id = Convert.ToString(dr["resource_id"]);
DayPilotScheduler1.Resources.Add(name, id);
}
r
}
How to define nurse shifts?
The scheduler control can generate the timeline (set of time cells) automatically from the start date and number of days.
We need a custom cell start and end so we will create a custom timeline:
Set Scale property to Manual
Add the custom time cells to Timeline collection.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadTimeline(DateTime.Today);
}
}
private void LoadTimeline(DateTime date)
{
DayPilotScheduler1.StartDate = date; // required for later refreshes (will be persisted)
DayPilotScheduler1.Scale = TimeScale.Manual;
const int firstShiftStartHour = 7; // first shift starts at 7 am
const int shiftDurationHours = 8; // one shift takes 8 hours
DateTime firstDayOfMonth = new DateTime(date.Year, date.Month, 1); // first day of month
int days = DateTime.DaysInMonth(firstDayOfMonth.Year, firstDayOfMonth.Month);
DateTime start = firstDayOfMonth.AddHours(firstShiftStartHour);
DateTime end = firstDayOfMonth.AddDays(days);
while (start < end)
{
DayPilotScheduler1.Timeline.Add(start, start.AddHours(shiftDurationHours));
start = start.AddHours(shiftDurationHours);
}
}
How to customize the Scheduler time header?
We will customize the time header cells (especially the date format) using BeforeTimeHeaderRender event handler.
protected void DayPilotScheduler1_OnBeforeTimeHeaderRender(object sender, BeforeTimeHeaderRenderEventArgs e)
{
if (e.Level == 1)
{
e.InnerHTML = e.Start.ToString("dddd, MMMM d");
}
if (e.Level == 2)
{
string start = TimeFormatter.GetHour(e.Start, TimeFormat.Clock12Hours, "{0}{1}").ToLower();
string end = TimeFormatter.GetHour(e.End, TimeFormat.Clock12Hours, "{0}{1}").ToLower();
e.InnerHTML = start + "-" + end;
}
}
How to load the shift assignment data?
Add the database column bindings to the scheduler control:
<DayPilot:DayPilotScheduler
ID="DayPilotScheduler1"
runat="server"
DataEndField="shift_start"
DataStartField="shift_end"
DataTextField="shift_name"
DataIdField="shift_id"
DataResourceField="resource_id"
/>
Load the database records:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DayPilotScheduler1.DataSource = DbLoadShiftData(DayPilotScheduler1.VisibleStart, DayPilotScheduler1.VisibleEnd);
DayPilotScheduler1.DataBind();
}
}
private DataTable DbLoadShiftData(DateTime start, DateTime end)
{
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM [shift] WHERE NOT (([shift_end] <= @start) OR ([shift_start] >= @end))", ConfigurationManager.ConnectionStrings["daypilot"].ConnectionString);
da.SelectCommand.Parameters.AddWithValue("start", start);
da.SelectCommand.Parameters.AddWithValue("end", end);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}