BetterCalendar
View a screen shot of this control.Storing Non-selectable Dates
Within the BetterCalendar.Render
method, a
System.Web.UI.WebControls.CalendarDay
and a
System.Web.UI.WebControls.TableCell
object is created for each day
in the calendar display. The OnDayRender
event is raised and these
two objects are passed to any DayRender
event handler assigned to
the control, just like Calendar
does.
After control returns from the event handler, the
CalendarDay.IsSelectable
property is checked. If it was set to
false
, that day's date is added to an ArrayList
.
// Create a list for storing nonselectable dates. ArrayList nonselectableDates = new ArrayList(); for (...) for (...) ... // Create a CalendarDay and a TableCell for the date. CalendarDay day = this.Day(date); TableCell cell = this.Cell(day); // Raise the OnDayRender event. this.OnDayRender(cell, day); // If the day was marked nonselectable, add it to the list. if (!day.IsSelectable) nonselectableDates.Add(day.Date.ToShortDateString());
The obvious thing to do would be to save this list to the view state.
However, since the control is being rendered, this will not work because the
control's SaveViewState
method has already been called.
Instead, the data is stored in a hidden field added to the page. A couple of
methods are defined to handle the conversion of the dates in the
ArrayList
to a suitable string value that can be stored in a
hidden form field and subsequently restored.
// // Saves a list of dates to the hidden form field. // private void SaveNonselectableDates(ArrayList dates) { // Build a string array by converting each date to a day count // value. string[] list = new string[dates.Count]; for (int i = 0; i < list.Length; i++) list[i] = this.DayCountFromDate( DateTime.Parse(dates[i].ToString())).ToString(); // Get the hidden field name. string fieldName = this.GetHiddenFieldName(); // For the field value, create a comma-separated list from the day // count values. string fieldValue = HttpUtility.HtmlAttributeEncode(String.Join(",", list)); // Add the hidden form field to the page. this.Page.RegisterHiddenField(fieldName, fieldValue); } // // Returns a list of dates stored in the hidden form field. // private ArrayList LoadNonselectableDates() { // Get the value stored in the hidden form field. string fieldName = this.GetHiddenFieldName(); string fieldValue = this.Page.Request.Form[fieldName]; // Extract the individual day count values. string[] list = fieldValue.Split(','); // Convert those values to dates and store them in an array list. ArrayList dates = new ArrayList(); foreach (string s in list) dates.Add(this.DateFromDayCount(Int32.Parse(s))); return dates; } // // Returns the name of the hidden field used to store nonselectable // dates on the form. // private string GetHiddenFieldName() { // Create a unique field name. return String.Format("{0}_NonselectableDates", this.ClientID); }
Within the RaisePostBackEvent
, when a range of dates is being
selected, we can load this list and use it to remove those dates.
... this.SelectedDates.Clear(); this.SelectedDates.SelectRange(date, date.AddDays(n - 1)); // If SelectAllInRange is false, remove any dates found // in the nonselectable date list. if (!this.SelectAllInRange) { ArrayList nonselectableDates = this.LoadNonselectableDates(); foreach(DateTime badDate in nonselectableDates) this.SelectedDates.Remove(badDate); }
Downloads
- BetterCalendar_src.zip - Source files (32KB)
- BetterCalendar_demo.zip - Demo project (22KB)