Archive

Posts Tagged ‘DayRender’

Supporting Multiple Dates in .NET Calendar Control

December 25, 2009 1 comment

This post will help you to support using multiple dates in a calendar control.  You will be able to populate your control with multiple dates from a data source, and then allow your users to interact with those selections, selecting or deselecting additional or existing dates for saving back to your data source.

The calendar control does not support databinding, so you have to use the DayRender event to make your selections appear.   You’ll also need to use the SelectionChanged event to manage selections and then some kind of a persistent storage that can live on the page like a session or use the viewstate bag.

So, anything coming in from the database gets handled in the DayRender event, and any changes get handled in the SelectionChanged event.  All of this should point to persistant storage such as a session variable or in the view state.  When you want to save what the user did, grab whatever you have in your session or view state and send it back to the database.

Here is my html for the control.

<asp:calendar id="cSeminarDate" runat="server" enableviewstate="true"
	daynameformat="Shortest" cssclass="CalendarStandard"
	onselectionchanged="cSeminarDate_SelectionChanged"
	ondayrender="cSeminarDate_DayRender">
	<dayheaderstyle cssclass="CalendarStandardDayHeaderStyle" />
	<daystyle cssclass="CalendarStandardDayStyle" />
	<nextprevstyle cssclass="CalendarStandardNextPrevStyle" />
	<othermonthdaystyle cssclass="CalendarStandardOtherMonthDayStyle" />
	<selecteddaystyle cssclass="CalendarStandardSelectedDayStyle" />
	<selectorstyle cssclass="CalendarStandardSelectorStyle" />
	<titlestyle cssclass="CalendarStandardTitleStyle" />
	<todaydaystyle cssclass="CalendarStandardTodayDayStyle" />
	<weekenddaystyle cssclass="CalendarStandardWeekendDayStyle" />
</asp:calendar>

What I did in this example was to create a session variable to store a List<DateTime>.   After populating my list with selected dates elsewhere in code, in the DayRender event (this event fires for every date in the calendar control), I compared the date that the control was currently drawing with my list, and if there was a match, I set the cell’s css class property to my selector style.

The following code is what I am using to populate my calendar control with selected dates.

protected void cSeminarDate_DayRender( object sender, DayRenderEventArgs e )
{
	List<DateTime> dt = SessionManager.GetInstance( HttpContext.Current ).SeminarDateList;
	foreach ( DateTime d in dt )
	{
		if ( d.ToShortDateString() == e.Day.Date.ToShortDateString() )
		{
			e.Cell.CssClass = "CalendarStandardSelectorStyle";
		}
	}
}

After I have my calendar populated with selected dates, my users are now in a position to deselect existing dates as well as to add new dates.  The following code below uses the SelectionChanged event in conjunction with the session.

protected void cSeminarDate_SelectionChanged( object sender, EventArgs e )
{
	if ( SessionManager.GetInstance( HttpContext.Current ).SeminarDateList.Contains(cSeminarDate.SelectedDate) )
	{
		SessionManager.GetInstance( HttpContext.Current ).SeminarDateList.Remove( cSeminarDate.SelectedDate );
		cSeminarDate.SelectedDates.Remove( cSeminarDate.SelectedDate );
	}
	else
	{
		SessionManager.GetInstance( HttpContext.Current ).SeminarDateList.Add( cSeminarDate.SelectedDate );
	}

	foreach ( DateTime dt in SessionManager.GetInstance( HttpContext.Current ).SeminarDateList )
	{
		cSeminarDate.SelectedDates.Add( dt );
	}
}

Where you see references to SessionManager.GetInstance( HttpContext.Current ).SeminarDateList, you can replace with Session[“SeminarDateList” ] as I manage my sessions explicitly in a single location.  Make sure to remember to clear your session when you init your page.  I have an InitUI() method I call if not a postback in the Page_Load event and elsewhere.  In there I do this 

SessionManager.GetInstance( HttpContext.Current ).SeminarDateList.Clear();

Hope this helps.

Advertisements
%d bloggers like this: