BetterCalendar
View a screen shot of this control.Note: This is a reprint of an article submitted to The Code Project.
Introduction
BetterCalendar is a custom control derived from
System.Web.UI.WebControls.Calendar. It is designed to correct some
problems with the Calendar control and add some additional
functionality.
Background
The Calendar control is quite useful but it has a few bugs and
drawbacks:
-
It's impossible to set a calendar's appearance using only style sheets (i.e., assigning class names to the
CssClassproperty on the various calendar style elements). This is because the control embeds inlinestyleattributes for many elements when style properties are defaulted.For example, the HTML for a day cell might look like:
<td class="calendarDay" align="Center" style="width:12%;"> <a href="javascript:__doPostBack('Calendar1','1566')" style="color:Black">15</a></td>Here, the color setting of
styleattribute will override any color setting in thecalendarDayclass. -
While you can define different styles for a day based on certain conditions - via the
DayStyle,WeekendDayStyle,OtherMonthDayStyle,TodayDayStyleandSelectedDayStyleproperties - only one style class is assigned even when more than one may apply.In other words, if today's date falls on a week end and it is selected on the control, the
SelectedDayStylestyle takes precedence:<td class="selectedDay_style" ... >Since an HTML element may be assigned multiple class names in its
classattribute, it's possible to include all applicable style classes like this:<td class="day_style weekendDay_style todayDay_style selectedDay_style" ... >
This would give you full control over how it appeared via a style sheet.
-
Using the
DayRenderevent, you can control which days are selectable and which are not. However, when week or month selectors are active on the control, all days in the given week or month are included in the selection, regardless of whether they are individually selectable or not. You could use theSelectionChangedevent to manually remove such dates, but that's doing the same work twice. -
Lastly, there is no limit on the next and previous month navigation controls. You can pro grammatically prevent viewing of months outside some range via the
VisibleMonthChangedevent, but the next and previous links are always rendered on the control.
The BetterCalendar control addresses these issues.
Using the code
The control is packaged in a class library with the namespace
BrainJar.Web.UI.WebControls which contains only the one class,
BetterCalendar.
Within a Visual Studio web project, you can simply add a reference to the
BrainJar.Web.UI.WebControls.dll file. You can then edit your web form in
HTML view and add the appropriate @ Register directive and tags. A
typical example is shown below (note the inclusion of an external style
sheet).
<%@ Page language="c#" Codebehind="WebForm2.aspx.cs"
AutoEventWireup="false" Inherits="Demo.WebForm2" %>
<%@ Register TagPrefix="BrainJar" Namespace="BrainJar.Web.UI.WebControls"
Assembly="BrainJar.Web.UI.WebControls"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name=vs_defaultClientScript content="JavaScript">
<meta name=vs_targetSchema
content="http://schemas.microsoft.com/intellisense/ie5">
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<link href="Styles.css" type="text/css" rel="stylesheet">
</HEAD>
<body>
<form id="WebForm1" method="post" runat="server">
<h1>BetterCalendar Control Demo</h1>
<BrainJar:BetterCalendar id="BetterCalendar1" runat="server">
<DayStyle CssClass="calendarDay"></DayStyle>
<DayHeaderStyle CssClass="calendarDayHeader"></DayHeaderStyle>
<NextPrevStyle CssClass="calendarNextPrev"></NextPrevStyle>
<OtherMonthDayStyle CssClass="calendarOtherMonthDay">
</OtherMonthDayStyle>
<SelectedDayStyle CssClass="calendarSelectedDay"></SelectedDayStyle>
<SelectorStyle CssClass="calendarSelector"></SelectorStyle>
<TitleStyle CssClass="calendarTitle"></TitleStyle>
<TodayDayStyle CssClass="calendarTodayDay"></TodayDayStyle>
<WeekendDayStyle CssClass="calendarWeekendDay"></WeekendDayStyle>
</BrainJar:BetterCalendar>
</form>
</body>
</HTML>
You can also add the control to the toolbox in the usual way (in Design mode, right-click on the toolbox, select "Customize Toolbox...", select the ".NET Framework Components" tab, press the "Browse" button and select the BrainJar.Web.UI.WebControls.dll file).
Since BetterCalendar is derived from the Calendar
control, it inherits all of that control's properties, methods and events. In
addition to those, it defines four new properties:
SelectAllInRange(Boolean)For use with week and month selectors (see the
Calendar.SelectionModeproperty documentation). If set totrue, all dates in a given week or month are selected. When set tofalse, only dates that are individually selectable are included. The default isfalse. See the demo project for an example of how this affects the control.ShowLinkTitles(Boolean)Setting this property to
trueaddstitleattributes to the links rendered on the control with text describing their function. For example, the previous month navigation link will be given a title like "View December, 2003."Using titles can improve the accessibility of your web form. Many browsers render
titleinformation in a tool tip, but specialized browsers may render it in speech or Braille.Warning: Although day and month names and dates are generated according to the current culture, the remaining title text is in English.
MaxVisibleDate(DateTime)Sets an upper limit on the month the user can navigate to using the next month navigation link. When the currently viewed month is the same as
MaxVisibleDate, the next month navigation link is omitted from the display.MinVisibleDate(DateTime)Sets a lower limit on the month the user can navigate to using the next month navigation link. When the currently viewed month is the same as
MinVisibleDate, the previous month navigation link is omitted from the display.
Note that both MixVisibleDate and MaxVisibleDate
default to System.DateTime.MinValue, which is interpreted to mean
that no limit is set.
Design-Time Support
BetterCalendar includes metadata for design-time support in
Visual Studio .NET, so the new properties will appear in the Properties window
when editing an instance of the control in Design view.
While it's not necessary in order to use the control, the source code includes a file named BrainJar.xsd that can be used to remove those embarrassing red squiggly lines when editing the control in HTML view.
To use the schema, copy BrainJar.xsd to your
vs_install_directory\Common7\Packages\schemas\xml directory (where
vs_install_directory is the directory Visual Studio .NET was installed
in, usually C:\Program Files\Microsoft Visual Studio .NET). Then add a
declaration for it in the BODY tag of your web form:
<body xmlns:BrainJar="urn:http://schemas.brainjar.com/AspNet/WebControls">
To add Intellisense support for the control when editing your code-behind, you can copy the BrainJar.Web.UI.WebControls.xml file from the project source (in the \debug directory) to your project's \bin directory.