Click here to Skip to main content
15,892,072 members
Articles / Web Development / ASP.NET

Databound Schedule Controls

Rate me:
Please Sign up or sign in to vote.
4.82/5 (176 votes)
24 Mar 2013LGPL321 min read 2.2M   42.2K   632  
These data controls can show scheduled events automatically
<!-- HTML for article "Databound Schedule controls" by Jos Branders
     URL: http://www.codeproject.com/aspnet/schedule.asp

     Article content copyright Jos Branders
     All formatting, additions and alterations Copyright � CodeProject, 1999-2005
-->
<!----------------------------- Article Starts ----------------------------->
<UL class=download>
  <LI><A 
  href="http://www.codeproject.com/aspnet/schedule/schedule_src.zip">Download 
  source files - 745 kB </A>
  <LI><A 
  href="http://www.codeproject.com/aspnet/schedule/schedule_demo.zip">Download 
  ASP.NET 1.x demo files - 96 kB </A>
  <LI><A 
  href="http://www.codeproject.com/aspnet/schedule/schedule_vsdemo.zip">Download 
  Visual Studio 2003 demo files - 118 kB </A></LI>
  <LI><A 
  href="http://www.codeproject.com/aspnet/schedule/schedule_2005demo.zip">Download 
  ASP.NET 2.0 demo files - 105 kB </A></LI>
</UL>
<A href="#intro">Introduction</A><BR>
<A href="#license">License</A><BR>
<A href="#installation">Installation</A><BR>
<A href="#usage">How to use</A><BR>
<A href="#howitworks">How it works</A><BR>
<A href="#pointsofinterest">Points of interest</A><BR>
<A href="#future">Future</A><BR>
<A href="#history">Update history</A> 
<H2><A name=intro></A>Introduction </H2>
<P>These are&nbsp;2 free controls, <STRONG>ScheduleCalendar</STRONG> and 
<STRONG>ScheduleGeneral</STRONG>,&nbsp;designed to show scheduled events in the 
form of a table. They are simple versions of the so-called Gantt chart. They 
don't have advanced features such as dependencies and milestones, but on the 
other hand, they use templated databinding, so it's up to you, the developer, 
what you want to show. </P>
<P>The controls can be used for a broad variety of applications: time tables, 
resource usage planners, calendars, event schedulers, activities, reservations, 
sequences, project management, etc... See the demos for some examples. </P>
<P>The <B>ScheduleCalendar</B> control for instance will turn this data: </P>
<TABLE cellSpacing=0 border=1>
  <THEAD>
  <TR>
    <TH>StartTime</TH>
    <TH>EndTime</TH>
    <TH>EventDate</TH>
    <TH>Task</TH></TR></THEAD>
  <TBODY>
  <TR>
    <TD align=right>9:00</TD>
    <TD align=right>11:00</TD>
    <TD align=right>3/8/2004</TD>
    <TD>History</TD></TR>
  <TR vAlign=top>
    <TD align=right>9:00</TD>
    <TD align=right>10:00</TD>
    <TD align=right>3/9/2004</TD>
    <TD>Math</TD></TR>
  <TR vAlign=top>
    <TD align=right>10:00</TD>
    <TD align=right>11:00</TD>
    <TD align=right>3/9/2004</TD>
    <TD>Biology</TD></TR>
  <TR vAlign=top>
    <TD align=right>11:00</TD>
    <TD align=right>12:00</TD>
    <TD align=right>3/9/2004</TD>
    <TD>History</TD></TR>
  <TR vAlign=top>
    <TD align=right>9:00</TD>
    <TD align=right>10:00</TD>
    <TD align=right>3/10/2004</TD>
    <TD>Geology</TD></TR>
  <TR vAlign=top>
    <TD align=right>10:00</TD>
    <TD align=right>12:00</TD>
    <TD align=right>3/10/2004</TD>
    <TD>Math</TD></TR>
  <TR vAlign=top>
    <TD align=right>9:00</TD>
    <TD align=right>10:00</TD>
    <TD align=right>3/11/2004</TD>
    <TD>Economy</TD></TR>
  <TR>
    <TD align=right>10:00</TD>
    <TD align=right>12:00</TD>
    <TD align=right>3/11/2004</TD>
    <TD>Literature</TD></TR>
  <TR vAlign=top>
    <TD align=right>9:00</TD>
    <TD align=right>12:00</TD>
    <TD align=right>3/12/2004</TD>
    <TD>Sports</TD></TR>
  <TR>
    <TD align=right>9:00</TD>
    <TD align=right>11:00</TD>
    <TD align=right>3/15/2004</TD>
    <TD>History</TD></TR>
  <TR vAlign=top>
    <TD align=right>9:00</TD>
    <TD align=right>10:00</TD>
    <TD align=right>3/16/2004</TD>
    <TD>Math</TD></TR>
  <TR vAlign=top>
    <TD align=right>10:00</TD>
    <TD align=right>11:00</TD>
    <TD align=right>3/16/2004</TD>
    <TD>Biology</TD></TR>
  <TR vAlign=top>
    <TD align=right>11:00</TD>
    <TD align=right>12:00</TD>
    <TD align=right>3/16/2004</TD>
    <TD>History</TD></TR>
  <TR vAlign=top>
    <TD align=right>9:00</TD>
    <TD align=right>10:00</TD>
    <TD align=right>3/17/2004</TD>
    <TD>Geology</TD></TR>
  <TR vAlign=top>
    <TD align=right>10:00</TD>
    <TD align=right>12:00</TD>
    <TD align=right>3/17/2004</TD>
    <TD>Math</TD></TR>
  <TR vAlign=top>
    <TD align=right>9:00</TD>
    <TD align=right>10:00</TD>
    <TD align=right>3/18/2004</TD>
    <TD>Economy</TD></TR>
  <TR>
    <TD align=right>10:00</TD>
    <TD align=right>12:00</TD>
    <TD align=right>3/18/2004</TD>
    <TD>Literature</TD></TR>
  <TR vAlign=top>
    <TD align=right>9:00</TD>
    <TD align=right>12:00</TD>
    <TD align=right>3/19/2004</TD>
    <TD>Sports</TD></TR></TBODY>
  <TFOOT></TFOOT></TABLE>
<P>into this presentation: </P>
<P><IMG src="schedule/demo1.gif" border=0> </P>
<P>The other control is the <STRONG>ScheduleGeneral</STRONG>. Here&nbsp;you can 
provide your own titles (you may think of people, resources or location names). 
Here's an example with TV stations: </P>
<P><IMG src="schedule/demo3.gif" border=0> </P>
<P>Automatically, overlapping events will cause extra rows or columns to be 
added to the table, so that they can be shown correctly. </P>
<P>Overlapping items:<BR><IMG src="schedule/overlapping.gif" border=0> </P>
<P>The controls are written in VB.NET, but they can be used in any ASP.NET 
application. You may need to slightly adapt some of the sample code below to 
match the language used in your application. </P>
<P>The controls come in two versions, one for ASP.NET 1.x (schedule.dll)
and one for ASP.NET 2.0 (schedule2.dll). The second version uses some of the
new classes in 2.0 to enable new features, such as declarative databinding
and smart tags. Each version comes with its own documentation file: 
"documentation.chm" is for 1.0 and "documentation2.chm" is for 2.0.
</P>

<H2><A name=license></A>License</H2>

<P>The controls are free and open source under the <A 
href="http://www.gnu.org/licenses/lgpl.html" target="_blank">LGPL license</A>.</P>

<H2><A name=installation></A>Installation </H2>

<H3>Installing the controls </H3>

<P>You can install the controls in the standard way: </P>
<UL>
  <LI>create a "bin" folder inside the application root of your website (if it's 
  not already there) 
  <LI>copy the assembly file schedule.dll (for ASP.NET 1.x) or schedule2.dll 
      (for ASP.NET 2.0) into the bin folder </LI></UL>
<P>You may want to add the controls to the toolbox of your editor (Visual 
Studio, Web Matrix or C# Builder). This will allow you to set their properties 
in the Property Pane. Follow the editor's procedure to add a control to the 
toolbox. </P>
<P>In order to support IntelliSense in HTML View in Visual Studio (and to avoid 
some compiler warnings):&nbsp; </P>
<UL>
  <LI>copy the schedule.xsd file to this folder
      <UL>
         <LI>VS 2003: <CODE>C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml</CODE> 
         <LI>VS 2005: <CODE>C:\Program Files\Microsoft Visual Studio 8\Common7\Packages\schemas\xml</CODE> </LI>
      </UL>
  <LI>modify the <CODE>&lt;body&gt;</CODE> tag of any new web form as follows: 
  <CODE lang=html>&lt;body 
  xmlns:cc1="urn:http://www.rekenwonder.com/schedule"&gt;</CODE> where cc1 is 
  the TagPrefix of the schedule control (the one assigned in the "Register" 
  directive). 
  </LI>
</UL>
<H3>Installing the demos</H3>
<P>I added three sets of demo files:&nbsp;<BR>
<ol>
  <li>a set of simple demo files with inline code, that can be used with Visual 
      Studio or Web Matrix with ASP.NET 1.x<BR>
  <li>a Visual Studio project with codebehind for ASP.NET 1.x.
  <li>a Visual Web Developer 2005 (or Visual Studio 2005) project with inline 
       code for ASP.NET 2.0</li>
</ol>

<P>Unzip the zipfile with the demos to a subfolder of the wwwroot folder. Then, 
either create a virtual directory for this folder in IIS, or copy the 
schedule.dll or schedule2.dll file to the bin folder in wwwroot.</P>

<P>For the demo files with inline code, that's all you have to do. Just call the 
first demo page through the address 
http://localhost/&lt;foldername&gt;/demo1.aspx in your browser.</P>

<P>For the Visual Studio project, open Visual Studio and create a new blank 
solution. Right click the new solution in the Solution Explorer, choose Add - 
New Project From Web..., enter the url http://localhost/&lt;foldername&gt; 
(&lt;foldername&gt; is the folder where you unzipped the demo files), and click 
OK. Select the project file when prompted. You should also create a virtual 
directory for the demo folder.</P>

<P>For the Visual Web Developer 2005 project, open Visual Web Developer
and choose "Open existing Web site". Browse to the folder where the demo
files are located.</P>

<H2><A name=usage></A>Using the controls </H2>

<H3>Adding the controls to your page </H3>

<P>There are 2 ways to add the controls to your page:</P>
<OL>
  <LI>Drag the control from the toolbox onto the page (if it was installed on 
  the toolbox). Be careful to select the correct type: 
  <STRONG>ScheduleCalendar</STRONG> for a weekly calendar schedule, 
  <STRONG>ScheduleGeneral</STRONG> for other schedules. 
  <LI>Add the code manually. Add this line to the top of your page:<PRE lang=asp.net>&lt;%@ Register TagPrefix="rw" Namespace="rw" Assembly="Schedule" %&gt;</PRE>Then, 
  add a tag like this where you want the schedule to be displayed: <PRE lang=asp.net>&lt;rw:ScheduleGeneral id="Schedule1" runat="server" &gt;
     &lt;ItemTemplate&gt;
     &lt;/ItemTemplate&gt;
&lt;/rw:ScheduleGeneral&gt;</PRE>
  Of course, for the calendar version, you use ScheduleCalendar.<BR><BR>
  If you're using code-behind, you should also add a reference to the 
  Schedule instance in your page class, like this: 
  <PRE lang=vb>Protected WithEvents Schedule1 As rw.ScheduleGeneral</PRE>
  In the code-behind page, also add this import statement: 
  <PRE lang=vb>Imports rw</PRE>
  </LI>
</OL>
<H3>Setting the control's properties </H3>
<P>Make sure you use the appropriate settings. </P>
<P>The <CODE>DataSource</CODE> property should be either a <CODE>DataSet</CODE>, 
a <CODE>DataTable</CODE> or a <CODE>DataView</CODE>. You can't databind to a 
<CODE>DataReader</CODE>, since the control must be able to sort the data 
internally. </P>
<P>For each item on the schedule, the data source should provide a single record 
containing a start value, an end value, and custom data (typically a description 
of the task or event). For the ScheduleCalendar control when 
<CODE>TimeFieldsContainDate=false</CODE>, you also need a date value. For the 
ScheduleGeneral control you also need a title value (for display on column/row 
headers). </P>
<P>You need to set 3 properties (similar to the 2 properties 
<CODE>DataTextField</CODE> and <CODE>DataValueField</CODE> that you have to set 
for a bound ListBox or CheckBoxList): </P>
<P><B>ScheduleCalendar</B>: </P>
<OL>
  <LI><CODE>StartTimeField</CODE>: the database field (column) containing the 
  start of the event 
  <LI><CODE>EndTimeField</CODE>: the database field containing the end of the 
  event 
  <LI><CODE>DateField</CODE>: the database field providing the dates. This field 
  should be of type "Date" (exception: when 
  <CODE>TimeFieldsContainDate</CODE><CODE>=true </CODE>this field is ignored, 
  see below). In a vertical layout, this field will be used for column titles. 
  In a horizontal layout, it will be used for row titles. </LI></OL>
<P><B>ScheduleGeneral</B>:</P>
<OL>
  <LI><CODE>DataRangeStartField</CODE>: the database field (column) containing 
  the start of the event 
  <LI><CODE>DataRangeEndField</CODE>: the database field containing the end of 
  the event 
  <LI><CODE>TitleField</CODE>: the database field providing the titles. You can 
  think of some useful fields for titles: people names, locations, classrooms, 
  resources, etc...) In a vertical layout, this field will be used for column 
  titles. In a horizontal layout, it will be used for row titles. </LI></OL>
<P>1) and 2) can be thought of as time fields, but in general, any type of 
sortable field (such as an integer) will do. Only when 
<CODE>TimeFieldsContainDate=true </CODE>for the ScheduleCalendar control, they 
should contain date and time information, and when 
<CODE>FullTimeScale=True</CODE>, they should contain at least time information. 
</P>
<P>Note that there is no property to indicate which field contains the "Task" or 
"Event" information. Actually, this information can be anything: a field, a 
combination of multiple fields, etc... This is possible since the "Task" data is 
provided through a databinding expression in the Item template. Its simplest 
form would be something like this for ASP.NET 1.x:</P>
<PRE lang=asp.net>&lt;ItemTemplate&gt;
   &lt;%# DataBinder.Eval(Container.DataItem,"taskfieldname") %&gt;
&lt;/ItemTemplate&gt;</PRE>
<P>and for ASP.NET 2.0:</P>
<PRE lang=asp.net>&lt;ItemTemplate&gt;
   &lt;%# Eval("taskfieldname") %&gt;
&lt;/ItemTemplate&gt;</PRE>
<P></P>
<P>Optionally, you can set the <CODE>ItemStyleField</CODE>. When its value is 
not blank, the database field with this name will be used as a css style class 
for the item. This lets you set the style for each item separately from the 
data source. </P>
<P>Then, there's the <CODE>FullTimeScale</CODE><B> </B>property. When false (the 
default value), only range values occurring in the data source are shown. When 
true, a continuous time scale is displayed (like the Outlook calendar). For the 
ScheduleGeneral control, this requires the <CODE>DataRangeStartField</CODE> and 
<CODE>DataRangeEndField</CODE> fields in the data source to be of type 
Date/Time.&nbsp; </P>
<P>The image below shows the the same item (Lunch from 12:30 to 13:30) in both 
cases: </P>
<TABLE id=table1 border=0>
  <TBODY>
  <TR>
    <TD>
      <P><CODE>FullTimeScale = false </CODE>
      <TABLE id=table2 border=1>
        <TBODY>
        <TR>
          <TD bgColor=#c0c0c0>12:30</TD>
          <TD bgColor=#ffffcc>
            <P>Lunch from 12:30 to 13:30</P></TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>13:30</TD>
          <TD></TD></TR></TBODY></TABLE></P></TD></TR></TBODY></TABLE>
<TABLE border=0>
  <TBODY>
  <TR>
    <TD>
      <P><CODE>FullTimeScale = true and TimeScaleInterval = 15 </CODE>
      <TABLE border=1>
        <TBODY>
        <TR>
          <TD bgColor=#c0c0c0>12:30</TD>
          <TD bgColor=#ffffcc rowSpan=4>
            <P>Lunch from 12:30 to 13:30</P></TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>12:45</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>13:00</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>13:15</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>13:30</TD>
          <TD></TD></TR></TBODY></TABLE></P></TD></TR></TBODY></TABLE>
<P>When <CODE>FullTimeScale</CODE> is true, there are 3 additional properties 
that you can set: </P>
<OL>
  <LI><CODE>TimeScaleInterval</CODE>: an integer value giving the number of 
  minutes for the interval (default=60) 
  <LI><CODE>StartOfTimeScale</CODE>: a timespan value setting the start time of 
  the time scale (default=8:00) 
  <LI><CODE>EndOfTimeScale</CODE>: a timespan value setting the end time of the 
  time scale (default=17:00). The highest value allowed here is 24:00 
  (midnight), which should be entered as "1.00:00" (one day, zero hours and 
  minutes). </LI></OL>
<P>Two other important properties are <CODE>IncludeEndValue</CODE> and <CODE>ShowValueMarks</CODE>. When <CODE>IncludeEndValue</CODE> is <CODE>True</CODE>, the row with the end value will be included in the event. 
Sometimes, this will result in a more logical presentation. However, when the items are adjacent (for 
instance: one event ends at 10:00 AM, and another starts at the same time), it's 
better to set <CODE>IncludeEndValue</CODE> to <CODE>False</CODE>.  Otherwise, the items will be shown as overlapping. In this case, you can also set <CODE>ShowValueMarks</CODE> to <CODE>True</CODE>, which will add marks indicating the values, and the values will be shown in the middle of the item.
The default value is <CODE>False</CODE> for both. 
</P>
<P>The image below shows the the same item (Lunch from 12:30 to 13:30) in all cases: </P>
      <P><CODE>IncludeEndvalue = False and ShowValueMarks = False</CODE>
      <TABLE border="1" bordercolor="Gray" CellSpacing="0">
        <TBODY>
        <TR>
          <TD bgColor=#c0c0c0>12:30</TD>
          <TD bgColor=#ffffcc rowSpan=2>
            <P>Lunch from 12:30 to 13:30</P></TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>13:00</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>13:30</TD>
          <TD></TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>14:00</TD>
          <TD></TD>
        </TR>
        </TBODY>
      </TABLE>
      </P>
      <P><CODE>IncludeEndValue = True (ShowValueMarks is ignored)</CODE>
      <TABLE border="1" bordercolor="Gray" CellSpacing="0">
        <TBODY>
        <TR>
          <TD bgColor=#c0c0c0>12:30</TD>
          <TD bgColor=#ffffcc rowSpan=3>
            <P>Lunch from 12:30 to 13:30</P></TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>13:00</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>13:30</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>14:00</TD>
          <TD></TD>
        </TR>
        </TBODY>
      </TABLE>
      </P>
      <P><CODE>IncludeEndValue = False and ShowValueMarks = True </CODE>
      <TABLE border="1" bordercolor="Gray" CellSpacing="0">
        <TBODY>
        <TR>
          <TD bgColor=#c0c0c0 style="border-right:none" rowspan="2">12:30</TD>
          <TD bgColor=#c0c0c0 style="border-left:none" >&nbsp;</TD>
          <TD></TD>
        </TR>
        <TR>
          <TD bgColor="#c0c0c0" style="border-left:none">&nbsp;</TD>
          <TD bgColor="#ffffcc" rowSpan="4" >
            <P>Lunch from 12:30 to 13:30</P>
          </TD>
        </TR>
        <TR>
          <TD bgColor=#c0c0c0 style="border-right:none" rowspan="2">13:00</TD>
          <TD bgColor=#c0c0c0 style="border-left:none">&nbsp;</TD>
        </TR>
        <TR>
          <TD bgColor=#c0c0c0 style="border-left:none">&nbsp;</TD>
        </TR>
        <TR>
          <TD bgColor=#c0c0c0 style="border-right:none" rowspan="2">13:30</TD>
          <TD bgColor=#c0c0c0 style="border-left:none">&nbsp;</TD>
        </TR>
        <TR>
          <TD bgColor=#c0c0c0 style="border-left:none">&nbsp;</TD>
          <TD rowspan="2"></TD>
        </TR>
        <TR>
          <TD bgColor=#c0c0c0 style="border-right:none" rowspan="2">14:00</TD>
          <TD bgColor=#c0c0c0 style="border-left:none">&nbsp;</TD>
        </TR>
        <TR>
          <TD bgColor=#c0c0c0 style="border-left:none">&nbsp;</TD>
          <TD></TD>
        </TR>
        </TBODY>
      </TABLE>
      </P>
<P>Finally, you may want to add functionality for inserting new items when 
the user clicks on an "empty slot" in the schedule. 
Set the <CODE>EnableEmptySlotClick</CODE> property to true, and handle the 
<CODE>OnEmptySlotClick</CODE> event. Optionally, set a
tooltip for empty slots with the <CODE>EmptySlotTooltip</CODE> property. 
For samples, see demo1 and demo2.</P> 
<P>For the <B>ScheduleCalendar</B> control, you should set these additional 
properties: </P>
<UL>
  <LI><CODE>NumberOfDays</CODE>: the number of days to show at a time. 
      The default value is 7, making it a weekly calendar. 
  <LI><CODE>NumberOfRepetitions</CODE>: the number of times to repeat the 
      number of days (the default setting is 1 repetition). 
      This will only work in vertical layout, meaning that the NumberOfDays
      is shown once on top, and repeated according to the setting of 
      NumberOfRepetitions. <BR>
      In horizontal layout, this value is ignored, and the number of days is
      shown only once. 
  <LI><CODE>StartDay</CODE>: the day of the week to start the calendar. 
      This property is only used when the NumberOfDays property is set to 7.
      The default value is Monday.
  <LI><CODE>StartDate</CODE>: date to start displaying events. If this date 
     is not on the same day of the week as the StartDay property, the control 
     will start displaying on the same day prior to the chosen date. 
     The default value is today's date. See the demos to 
     learn how to set today's date programmatically. 
  <LI><CODE>TimeFieldsContainDate</CODE>: when false (the default), the 
     <CODE>DateField</CODE> property is used to extract dates for each item. This 
     means that items must start and end on the same day. If some of your items 
     span midnight, you should set <CODE>TimeFieldsContainDate </CODE>to true, and 
     you should provide a full date and time in both the 
     <CODE>StartTimeField</CODE> and <CODE>EndTimeField</CODE> fields. In this 
     case, the <CODE>DateField</CODE> property is ignored. 
  </LI>
</UL>
<P>The <B>ScheduleGeneral</B> control has two additional properties: </P>
<UL>
  <LI><CODE>AutoSortTitles</CODE>: When true, the titles are sorted automatically,
     even when they are not sorted in the data source. When false, you may
     provide your own sorting order for the titles, but make sure that the items 
     with the same titles are grouped together, and that for each title, the 
     items are sorted on DataRangeStartField first and on DataRangeEndField next. 
     (for example: if you want to sort on a field called "SortOrder", 
     the DataRangeStartField is "StartTime",
     and the DataRangeEndField is "EndTime", use the sorting expression
     "ORDER BY SortOrder ASC, StartTime ASC, EndTime ASC")
     The default value for <CODE>AutoSortTitles</CODE> is true. 
  </LI>
  <LI><CODE>SeparateDateHeader</CODE>: When true, an extra range of cells will 
     be added to group all events of the same date. This requires 
     <CODE>DataRangeStartField</CODE> and <CODE>DataRangeEndField</CODE> to be of 
     type <CODE>DateTime</CODE>. The default is False. 
  </LI>
</UL>
<TABLE id=table5 border=0>
  <TBODY>
  <TR>
    <TD>
      <P><CODE>SeparateDateHeader=False </CODE>
      <TABLE id=table6 border=1>
        <TBODY>
        <TR>
          <TD bgColor=#c0c0c0>12/9/2004 14:00</TD>
          <TD align=middle bgColor=#ffffcc rowSpan=2>Task 1</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>12/9/2004 15:00</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>12/10/2004 14:00</TD>
          <TD align=middle bgColor=#ffffcc rowSpan=2>Task 2</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>12/10/2004 
  15:00</TD></TR></TBODY></TABLE></P></TD></TR></TBODY></TABLE>
<TABLE border=0>
  <TBODY>
  <TR>
    <TD>
      <P><CODE>SeparateDateHeader= True</CODE> 
      <TABLE border=1>
        <TBODY>
        <TR>
          <TD bgColor=#c0c0c0 rowSpan=2>12/9/2004</TD>
          <TD bgColor=#c0c0c0>14:00</TD>
          <TD align=middle bgColor=#ffffcc rowSpan=2>Task 1</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>15:00</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0 rowSpan=2>12/10/2004</TD>
          <TD bgColor=#c0c0c0>14:00</TD>
          <TD align=middle bgColor=#ffffcc rowSpan=2>Task 2</TD></TR>
        <TR>
          <TD bgColor=#c0c0c0>15:00</TD>
        </TR>
        </TBODY>
      </TABLE>
      </P>
    </TD>
  </TR>
  </TBODY>
</TABLE>
<P>For both the ScheduleCalendar and ScheduleGeneral controls, you can easily 
switch between a vertical or a horizontal layout with the 
<CODE>Layout</CODE> property, even at run time.</P>

<H3>Providing template content </H3>

<P>The next step is to add the content of the templates.</P>
<P>You can right-click on the control to edit the templates, or you can create 
the templates in HTML view. Also look at the templates in the demo pages for 
samples.</P>
<P>First of all, you should provide the </P>
<UL>
  <LI><CODE>ItemTemplate</CODE> </LI>
</UL>
<PRE lang=asp.net>&lt;ItemTemplate&gt;
   &lt;%# DataBinder.Eval(Container.DataItem,"taskfieldname") %&gt;
&lt;/ItemTemplate&gt;
</PRE>
With ASP.NET 2.0, you can use:
<PRE lang=asp.net>&lt;ItemTemplate&gt;
   &lt;%# Eval("taskfieldname") %&gt;
&lt;/ItemTemplate&gt;
</PRE>
If you want, you can combine information from several 
fields in the database. You can also add controls, images, just like you can in 
a Repeater or DataList control. 
<P>The other templates are for the headers. Especially in the case of a time and 
date fields, you may want to format the content for proper display.</P>
<P>For the <B>ScheduleGeneral</B> control:</P>
<UL>
  <LI><CODE>TitleTemplate</CODE> </LI></UL>
<P>You just show the data:</P><PRE lang=asp.net>&lt;TitleTemplate&gt;
     &lt;%# Container.DataItem %&gt; 
&lt;/TitleTemplate&gt;</PRE>
<UL>
  <LI><CODE>RangeHeaderTemplate</CODE> </LI></UL>
<P>Typically, you could display the range header item as a short time:</P><PRE lang=asp.net>&lt;RangeHeaderTemplate&gt;
   &lt;%# Convert.ToDateTime(Container.DataItem).ToShortTimeString() %&gt;
&lt;/RangeHeaderTemplate&gt;</PRE>
<UL>
  <LI><CODE>DateHeaderTemplate</CODE><B> </B>(only used when 
  <CODE>SeparateDateHeader</CODE> is set to <CODE>true</CODE>) </LI></UL>
<P>Typically, you could display the date header item as a short date:</P><PRE lang=asp.net>&lt;DateHeaderTemplate&gt;
   &lt;%# Convert.ToDateTime(Container.DataItem).ToShortDateString() %&gt;
&lt;/DateHeaderTemplate&gt;</PRE>
<P>For the <B>ScheduleCalendar</B> control:</P>
<UL>
  <LI><CODE>DateTemplate</CODE> </LI></UL>
<P>You could typically display the date header as a short date:</P><PRE lang=asp.net>&lt;TitleTemplate&gt;
   &lt;%# Convert.ToDateTime(Container.DataItem).ToShortDateString() %&gt;
&lt;/TitleTemplate&gt;</PRE>
<UL>
  <LI><CODE>TimeTemplate</CODE> </LI></UL>
<P>Typically, you could display the time header item as a short time:</P><PRE lang=asp.net>&lt;RangeHeaderTemplate&gt;
   &lt;%# Convert.ToDateTime(Container.DataItem).ToShortTimeString() %&gt;
&lt;/RangeHeaderTemplate&gt;</PRE>
<P>In your code, don't forget to call the <CODE>DataBind()</CODE> method. 
Without this call, nothing will be shown.</P>
<P>Finally, there's the <CODE>EmptyDataTemplate</CODE>. Optionally, you can
use this template to provide a message to be shown when no data is found in
the data source. This template is not used by the ScheduleCalendar control 
when FullTimeScale=True.</P>

<H3>New features in ASP.NET 2.0</H3>

<p>The controls can now be bound to a DataSourceControl, just like you can 
with a GridView control. Use the smart tag menu and the "Select Data Source" wizard.</p>

<p>The Schedule control can also be used in Master/Detail scenarios. Typically, you
can link it to a FormView or a DetailsView control, which allows for easy
editing of data items. Make sure to include a primary key field in the data
source for the Schedule control, and set the DataKeyNames property to the
name of that primary key field.</p>

<p>After adding the FormView or the DetailsView control, use the "Select Data Source"
wizard. Use the WHERE button to link the control to the Schedule control.</p>

<H3><A name=upgrade1.5></A>Upgrading from a version prior to 1.5 </H3>

<P>If you have projects working with a version prior to 1.5, you need to upgrade them.<BR>
The Schedule class has been removed from the assembly, from now on you'll have to use either 
ScheduleCalendar or ScheduleGeneral. </P>
<P>If your project contains a Schedule control with <B>DisplayMode=Calendar</B>: 
</P>
<UL>
  <LI>Change the control's type from Schedule to ScheduleCalendar (just change 
  the type manually in the page and in the codebehind file if you use one) 
  <LI>Rename the TitleTemplate into a DateTemplate (with the same content) 
  <LI>Rename the RangeHeaderTemplate into a TimeTemplate (with the same content) 

  <LI>Rename the TitleField property into a DateField property (with the same 
  value) 
  <LI>Rename the RangeHeaderStartField property into a StartTimeField property 
  (with the same value) 
  <LI>Rename the RangeHeaderEndField property into an EndTimeField property 
  (with the same value) 
  <LI>Rename the UseTitleFieldAsDate property into a TimeFieldsContainDate 
  property (with the <B>opposite</B> value, change true into false and false 
  into true) 
  <LI>Rename the TitleStyle tag to DateStyle, or remove it when there is a 
  DateStyle tag already 
  <LI>Rename the RangeHeaderStyle tag to TimeStyle, or remove it when there is a 
  TimeStyle tag already </LI></UL>
<P>If your project contains a Schedule control with <B>DisplayMode=General</B>: 
</P>
<UL>
  <LI>Change the control's type from Schedule into ScheduleGeneral (just change 
  the type manually in the page and in the codebehind file if you use one) 
  <LI>If some properties (such as Weeks, StartDate and UseTitleFieldAsDate) that 
  were not needed for DisplayMode=General were given a value anyway, remove 
  them. </LI></UL>
<H3>Demo pages </H3>
<P>Download the demo pages for samples showing you how the Schedule control 
could be used. In each sample, you can set the properties with the help of a 
form and you can add items. These samples use an Access database as the data 
source. </P>
<UL>
  <LI><B>demo1.aspx </B>shows a sample of a calendar. It also shows you how to 
  delete items with a linkbutton. 
  <LI><B>demo2.aspx </B>shows a sample of a task list. It also shows you how to 
  edit and delete items with a linkbutton. 
  <LI><B>demo3.aspx </B>shows a sample of a TV program schedule. 
  <LI><B>demo4.aspx </B>shows a sample of a calendar with items that span 
  midnight. </LI></UL>
<H2><A name=howitworks></A>How it works </H2>
<P>I decided to use a table for displaying all the items, instead of graphics. 
Graphics can put a heavy load on the server, and most importantly: a table can 
have child controls such as checkboxes and hyperlinks. By using templates, a 
developer has full control about the content of the items. </P>
<P>I used Microsoft's sample code for the <A 
href="http://msdn.microsoft.com/library/en-us/cpguide/html/cpcontemplateddataboundcontrolsample.asp" 
target=_blank>TemplatedList</A> control as a starting point. </P>
<P>I created a BaseSchedule control, which contains the code that is common for 
ScheduleGeneral and ScheduleCalendar.</P>
<P>First, all the information is extracted from the data source in order to 
create lists for the row and column headers. Any double values are removed, and 
the remainder is sorted in ascending order. </P>
<P>Next, an empty Table web control is built, with the correct number of rows 
and columns. </P>
<P>Then, the header items are added (row headers and column headers). </P>
<P>Finally, the scheduled items are added to the body of the table. The most 
difficult part is to calculate the position and span of each item, to merge the 
corresponding cells, and to check whether items don't overlap. </P>
<P>For the control to work correctly on postback, the control tree needs to be 
rebuilt in exactly the same way (without setting any properties). To make this 
possible, some information has to be stored in the control's 
<CODE>ViewState</CODE>:</P>
<UL>
  <LI>the number of rows 
  <LI>the number of cells in each row 
  <LI>the number of header cells in each row 
  <LI>the position (row and column index) of each item </LI></UL>
<P>In the <CODE>CreateChildControls</CODE> method, this information is used to 
build the control tree. </P>
<P>On postback, viewstate will be applied automatically to each child control, 
and their state will be restored magically. </P>
<P>For designer support, the controls are based on Andy Smith's&nbsp;<A 
href="http://weblogs.asp.net/asmith/articles/SimpleTemplatedControlDesigner.aspx" 
target=_blank>SimpleTemplatedControlDesigner</A> class. </P>

<p>For the ASP.NET 2.0 version, I derived from the new CompositeDataBoundControl class.
I added the SelectedValue property, in order to enable master/detail scenarios with
FormView and DetailsView controls.

<p>The designers are derived from the new DataBoundControlDesigner class, which 
   eliminates the need for the SimpleTemplatedControlDesigner code.

<p>I had a lot of trouble figuring out how to do it in ASP.NET 2.0, since a lot of 
documentation was still missing mid 2005.
</P>

<H2><A name=future></A>Future </H2>
<P>Here are some ideas for improvement: </P>
<UL>
  <LI>Add a <CODE>DeleteCommand</CODE> event 
  <LI>Add a <CODE>TodayStyle</CODE> property (similar to the one in the Calendar 
  control) 
  <LI>Provide support for right-to-left languages 
  <LI>Add dragging support for selecting a range (Outlook style) 
  <LI>Support for recurring events 
  <LI>Auto Format option
  <LI>Windows Forms version</LI>
</UL>
<P>If anyone decides to extend this control, or has any comments, bug reports or 
questions, then it would be great to hear from you. </P>
<H2><A name=pointsofinterest></A>Points of interest </H2>
<UL>
  <LI>templated control 
  <LI>databound control 
  <LI>control styles 
  <LI>designer support 
  <LI>property builders
  <LI>ASP.NET 2.0 databound control
  <LI>ASP.NET 2.0 designer action lists</LI>
</UL>
<H2><A name=history></A>Update history</H2>
<P>All releases are fully backwards compatible, except when upgrading from a 
version prior to 1.5 to version 1.6 or later. For this special case, see 
the <a href="#upgrade1.5">upgrading instructions above</a>. In all other cases, your existing 
projects will not stop working. 
</P>
<H4>Changes in release 2.1</H4>
<UL>
  <LI>On popular demand, I added the <CODE>OnEmptySlotClick</CODE> event. 
      To use it, set the <CODE>EnableEmptySlotClick</CODE> property to true, and
      optionally, add a value for the <CODE>EmptySlotTooltip</CODE> property.
      Handle the event in your page. See demo1 and demo2 for samples.</LI>
  <LI>Added the documentation2.chm help file with documentation for the version for .NET 2.0.</LI>
</UL>
<H4>Changes in release 2.0</H4>
<UL>
  <LI>Template editing from the smart tag menu is now working in VS2005.
  </LI>
</UL>
<H4>Changes in release 1.9</H4>
<UL>
  <LI><font color="red"><b>Support for ASP.NET 2.0.</b></font><br>
      The controls now support declarative binding to ASP.NET 2.0 data source controls. 
      The controls can also serve as master controls in connection with
      a FormView or DetailsView control. As with other ASP.NET 2.0 data controls,
      this enables you to create pages without writing any code.<br>
      There is only one set of source files, with conditional compilation.
      Use build.bat to build schedule.dll for ASP.NET 1.x and build2.bat to build 
      schedule2.dll for ASP.NET 2.0. Don't use both assemblies in the same 
      project. If you still want to upgrade your pages one by one, make two 
      sets of source files with different namespaces (e.g. rw and rw2).
  <LI>Added the <CODE>SelectedValue</CODE> property.
  <LI>Added the <CODE>SelectedIndexChanged</CODE> event.
  </LI>
</UL>
<H4>Changes in release 1.6.1</H4>
<UL>
  <LI>Added a new property <CODE>NumberOfDays</CODE> for the ScheduleCalendar
      control to allow for a number of days other than 7. The default value
      is still 7.
  </LI>
  <LI>Since the ScheduleCalendar control is not limited to a 7 day week anymore, 
      the Weeks property is replaced by the <CODE>NumberOfRepetitions</CODE> property.
      Setting the Weeks property will still work, but it will not show up in
      the property panel anymore.
  </LI>
  <LI>Added a new property <CODE>StartDay</CODE> for the ScheduleCalendar
      control to allow for a starting day other than Monday. This property is
      ignored when the NumberOfDays is not 7. The default value is still Monday.
  </LI>
</UL>
<H4>Changes in release 1.6</H4>
<UL>
  <LI>A new property <CODE>ShowValueMarks</CODE> allows for a better display of 
      adjacent items. See the demos and the explanation above.
  </LI>
  <LI>Added the possibility to add titles to the ScheduleGeneral control with no content. 
      This allows you to show all your titles at all times, even when they don't 
      have any scheduled items for the given period. In order to do this, you have to add 
      an extra row in your data source with a <code>DataRangeStartField</code> 
      value of NULL for every title that you want to show up 
      (this solution courtesy of K. B. McHugh).
  </LI>
  <LI>Added the <CODE>EmptyDataTemplate</CODE> property. Use this template to 
      provide content when no rows are found in the data source (typically, this
      would just be a message saying something like "No data found".
  </LI>
  <LI>
      Added a new property <CODE>ItemStyleField</CODE>, which is an optional 
      database field providing the item styles (in the form of a css class name). 
      If not provided, then the ItemStyle property and the AlternatingItemStyle
      property will be used for all items.
      This addition is courtesy of David Sanders.
  </LI> 
  <LI>
      Added a new property <CODE>AutoSortTitles</CODE> for the ScheduleGeneral
      control. When true (the default value), the titles are sorted alphabetically
      by the control according to the values in the RangeValueField (this was also
      the method used in previous versions). When false, the titles are
      not sorted by the control, and the order will be the one of the 
      items in the datasource. When using this option, make sure that the items
      with the same titles are grouped together in the datasource before databinding. 
      If the titles are not grouped, unexpected results may occur.
  </LI> 
  <LI>
      Renamed the database folder in the demos to "App_Data" instead of "db", in 
      preparation for ASP.NET 2.0 folder naming conventions.
  </LI> 
</UL>
<H4>Changes in release 1.5</H4>
<UL>
  <LI>The&nbsp;code now provides one base class (BaseSchedule) and 3 derived 
  controls: ScheduleCalendar,&nbsp;ScheduleGeneral and Schedule (this last one 
  is only for backwards compatibility). This will greatly simplify the setting 
  of their properties and templates, because only the relevant properties and 
  templates are shown for each type of control.&nbsp;<BR>The properties and 
  templates are also more self-explanatory, especially for the ScheduleCalendar 
  control.<BR><STRONG>Upgrading issues</STRONG>: <BR>Currently, you can leave 
  your existing projects as they are, because the included Schedule class 
  provides the same functionality as before, but I plan to&nbsp;remove this 
  class&nbsp;in the future. Therefore, I suggest that you convert your existing 
  projects. This can be done with a <A href="#upgrade1.5">few changes</A> only. 
  It will take you only a minute. 
  <LI>The source code is now split up in separate files for each class. 
  <LI>Added property&nbsp;builders for ScheduleCalendar and ScheduleGeneral. 
  <LI>Solved datasource property bug 
  <LI>Added "&amp;nbsp;" to empty cells 
  <LI>Databinding errors will now cause a page error (same behavior as in other 
  data controls), instead of silently being suppressed&nbsp; 
  <LI>Solved bug with databinding in header 
  <LI>Solved some minor bugs </LI>
</UL>
<H4>Changes in release 1.4</H4>
<UL>
  <LI>Support for items that span midnight in Calendar mode (on popular demand). 
  I added a new property "UseTitleFieldAsDate", which should be set to False if 
  you want to support items that span midnight. Automatically, these items will 
  be split into multiple items (one for each day), and added to the schedule. I 
  added an extra demo page to show you how to implement this situation. 
  <LI>The timescale can now go up to 24:00 hours (12:00 PM or midnight). I found 
  out that you can enter a 24:00 hours time span in the editor's property pane 
  by using a dot after the number of days ("1.00:00:00" is the same as 24 
  hours). 
  <LI>Solved the DataSource property bug (showing an error in the property 
  editor). 
  <LI>Added Visual Studio demo files 
  <LI>Solved bug with postback on header items (reported by Deraldo Messner) 
  <LI>Added toolbox bitmap 
  <LI>Important: when upgrading existing projects to this version, you may need 
  to replace the "rw" namespace with "schedule.rw". </LI>
</UL>
<H4>Changes in release 1.3</H4>
<UL>
  <LI>Support for designer template editing. 
  <LI>Solved some bugs. </LI>
</UL>
<H4>Changes in release 1.2</H4>
<UL>
  <LI>Much better designer support by deriving from TemplatedControlDesigner. 
  Almost any change in the properties settings will now automatically be 
  reflected in the designer. 
  <LI>Solved bugs when using Schedule with no data in General Mode (reported by 
  Beren Longstreet).&nbsp; 
  <LI>Added a schedule.xsd file for additional IntelliSense support in Visual 
  Studio </LI>
</UL>
<H4>Changes in release 1.1</H4>
<UL>
  <LI>Made the source code compile with Option Strict On. 
  <LI>Added a FullTimeScale option. Previously, only time values occurring in 
  the data source were used. With this option, the control will show a 
  continuous range of time values.</LI>
</UL>
<!----------------------------- Article Ends ----------------------------->

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Web Developer
Belgium Belgium
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions