2 // System.Web.UI.WebControls.Calendar.cs
5 // Jordi Mas i Hernandez (jordi@ximian.com)
7 // (C) 2005-2010 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Globalization;
33 using System.Collections;
34 using System.ComponentModel;
36 using System.Security.Permissions;
37 using System.Threading;
39 using System.Web.Util;
41 namespace System.Web.UI.WebControls
44 [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
45 [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
47 [DataBindingHandler("System.Web.UI.Design.WebControls.CalendarDataBindingHandler, " + Consts.AssemblySystem_Design)]
48 [DefaultEvent("SelectionChanged")]
49 [DefaultProperty("SelectedDate")]
50 [Designer("System.Web.UI.Design.WebControls.CalendarDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
51 [ControlValueProperty ("SelectedDate", "1/1/0001 12:00:00 AM")]
52 [SupportsEventValidation]
53 public class Calendar : WebControl, IPostBackEventHandler
55 TableItemStyle dayHeaderStyle;
56 TableItemStyle dayStyle;
57 TableItemStyle nextPrevStyle;
58 TableItemStyle otherMonthDayStyle;
59 TableItemStyle selectedDayStyle;
60 TableItemStyle titleStyle;
61 TableItemStyle todayDayStyle;
62 TableItemStyle selectorStyle;
63 TableItemStyle weekendDayStyle;
64 DateTimeFormatInfo dateInfo;
65 SelectedDatesCollection selectedDatesCollection;
67 DateTime today = DateTime.Today;
68 static DateTime dateZenith = new DateTime (2000, 1,1);
69 const int daysInAWeek = 7;
70 static readonly object DayRenderEvent = new object ();
71 static readonly object SelectionChangedEvent = new object ();
72 static readonly object VisibleMonthChangedEvent = new object ();
80 [WebSysDescription ("")]
81 [WebCategoryAttribute ("Appearance")]
82 public virtual string Caption {
83 get { return ViewState.GetString ("Caption", String.Empty); }
84 set { ViewState["Caption"] = value; }
87 [DefaultValue (TableCaptionAlign.NotSet)]
88 [WebSysDescription ("")]
89 [WebCategoryAttribute ("Accessibility")]
90 public virtual TableCaptionAlign CaptionAlign {
91 get { return (TableCaptionAlign)ViewState.GetInt ("CaptionAlign", (int)TableCaptionAlign.NotSet); }
92 set { ViewState ["CaptionAlign"] = value; }
96 [WebSysDescription ("")]
97 [WebCategory ("Layout")]
98 public int CellPadding {
99 get { return ViewState.GetInt ("CellPadding", 2); }
103 throw new ArgumentOutOfRangeException ("The specified cell padding is less than -1.");
105 ViewState ["CellPadding"] = value;
110 [WebSysDescription ("")]
111 [WebCategory ("Layout")]
112 public int CellSpacing {
113 get { return ViewState.GetInt ("CellSpacing", 0); }
117 throw new ArgumentOutOfRangeException ("The specified cell spacing is less than -1");
119 ViewState ["CellSpacing"] = value;
123 [PersistenceMode(PersistenceMode.InnerProperty)]
124 [NotifyParentProperty(true)]
125 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
126 [WebSysDescription ("")]
127 [WebCategory ("Style")]
128 public TableItemStyle DayHeaderStyle {
130 if (dayHeaderStyle == null) {
131 dayHeaderStyle = new TableItemStyle ();
132 if (IsTrackingViewState)
133 dayHeaderStyle.TrackViewState ();
136 return dayHeaderStyle;
140 [DefaultValue(DayNameFormat.Short)]
141 [WebSysDescription ("")]
142 [WebCategory ("Appearance")]
143 public DayNameFormat DayNameFormat {
144 get { return (DayNameFormat) ViewState.GetInt ("DayNameFormat", (int) DayNameFormat.Short); }
147 if (value != DayNameFormat.FirstLetter && value != DayNameFormat.FirstTwoLetters &&
148 value != DayNameFormat.Full && value != DayNameFormat.Short && value != DayNameFormat.Shortest) {
149 throw new ArgumentOutOfRangeException ("The specified day name format is not one of the DayNameFormat values.");
152 ViewState ["DayNameFormat"] = value;
157 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
158 [NotifyParentProperty(true)]
159 [PersistenceMode(PersistenceMode.InnerProperty)]
160 [WebSysDescription ("")]
161 [WebCategory ("Style")]
162 public TableItemStyle DayStyle {
164 if (dayStyle == null) {
165 dayStyle = new TableItemStyle ();
166 if (IsTrackingViewState)
167 dayStyle.TrackViewState ();
174 [DefaultValue(FirstDayOfWeek.Default)]
175 [WebSysDescription ("")]
176 [WebCategory ("Appearance")]
177 public FirstDayOfWeek FirstDayOfWeek {
178 get { return (FirstDayOfWeek) ViewState.GetInt ("FirstDayOfWeek", (int) FirstDayOfWeek.Default); }
181 if (value < FirstDayOfWeek.Sunday || value > FirstDayOfWeek.Default) {
182 throw new ArgumentOutOfRangeException ("The specified day name format is not one of the DayNameFormat values.");
185 ViewState ["FirstDayOfWeek"] = value;
189 [DefaultValue(">")]
191 [WebSysDescription ("")]
192 [WebCategory ("Appearance")]
193 public string NextMonthText {
194 get { return ViewState.GetString ("NextMonthText", ">"); }
195 set { ViewState ["NextMonthText"] = value; }
198 [DefaultValue(NextPrevFormat.CustomText)]
199 [WebSysDescription ("")]
200 [WebCategory ("Appearance")]
201 public NextPrevFormat NextPrevFormat {
202 get { return (NextPrevFormat) ViewState.GetInt ("NextPrevFormat", (int) NextPrevFormat.CustomText); }
205 if (value != NextPrevFormat.CustomText && value != NextPrevFormat.ShortMonth && value != NextPrevFormat.FullMonth)
206 throw new ArgumentOutOfRangeException ("The specified day name format is not one of the DayNameFormat values.");
208 ViewState ["NextPrevFormat"] = value;
212 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
213 [NotifyParentProperty(true)]
214 [PersistenceMode(PersistenceMode.InnerProperty)]
215 [WebSysDescription ("")]
216 [WebCategory ("Style")]
217 public TableItemStyle NextPrevStyle {
219 if (nextPrevStyle == null) {
220 nextPrevStyle = new TableItemStyle ();
221 if (IsTrackingViewState)
222 nextPrevStyle.TrackViewState ();
225 return nextPrevStyle;
230 [NotifyParentProperty(true)]
231 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
232 [PersistenceMode(PersistenceMode.InnerProperty)]
233 [WebSysDescription ("")]
234 [WebCategory ("Style")]
235 public TableItemStyle OtherMonthDayStyle {
237 if (otherMonthDayStyle == null) {
238 otherMonthDayStyle = new TableItemStyle ();
239 if (IsTrackingViewState)
240 otherMonthDayStyle.TrackViewState ();
243 return otherMonthDayStyle;
247 [DefaultValue("<")]
249 [WebSysDescription ("")]
250 [WebCategory ("Appearance")]
251 public string PrevMonthText {
252 get { return ViewState.GetString ("PrevMonthText", "<"); }
253 set { ViewState ["PrevMonthText"] = value; }
256 [Bindable(true, BindingDirection.TwoWay)]
257 [DefaultValue("1/1/0001 12:00:00 AM")]
258 [WebSysDescription ("")]
259 [WebCategory ("Appearance")]
260 public DateTime SelectedDate {
262 if (SelectedDates.Count > 0)
263 return SelectedDates [0];
265 return DateTime.MinValue;
268 set { SelectedDates.SelectRange (value, value); }
272 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
273 [WebSysDescription ("")]
274 [WebCategory ("Appearance")]
275 public SelectedDatesCollection SelectedDates {
277 if (dateList == null)
278 dateList = new ArrayList ();
280 if (selectedDatesCollection == null)
281 selectedDatesCollection = new SelectedDatesCollection (dateList);
283 return selectedDatesCollection;
288 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
289 [NotifyParentProperty(true)]
290 [PersistenceMode(PersistenceMode.InnerProperty)]
291 [WebSysDescription ("")]
292 [WebCategory ("Style")]
293 public TableItemStyle SelectedDayStyle {
295 if (selectedDayStyle == null) {
296 selectedDayStyle = new TableItemStyle ();
297 if (IsTrackingViewState)
298 selectedDayStyle.TrackViewState ();
301 return selectedDayStyle;
305 [DefaultValue(CalendarSelectionMode.Day)]
306 [WebSysDescription ("")]
307 [WebCategory ("Behavior")]
308 public CalendarSelectionMode SelectionMode {
309 get { return (CalendarSelectionMode) ViewState.GetInt ("SelectionMode", (int) CalendarSelectionMode.Day); }
312 if (value != CalendarSelectionMode.Day && value != CalendarSelectionMode.DayWeek &&
313 value != CalendarSelectionMode.DayWeekMonth && value != CalendarSelectionMode.None) {
314 throw new ArgumentOutOfRangeException ("The specified selection mode is not one of the CalendarSelectionMode values.");
316 ViewState ["SelectionMode"] = value;
320 [DefaultValue(">>")]
322 [WebSysDescription ("")]
323 [WebCategory ("Appearance")]
324 public string SelectMonthText {
325 get { return ViewState.GetString ("SelectMonthText", ">>"); }
326 set { ViewState ["SelectMonthText"] = value; }
329 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
330 [NotifyParentProperty(true)]
331 [PersistenceMode(PersistenceMode.InnerProperty)]
332 [WebSysDescription ("")]
333 [WebCategory ("Style")]
334 public TableItemStyle SelectorStyle {
336 if (selectorStyle == null) {
337 selectorStyle = new TableItemStyle ();
338 if (IsTrackingViewState)
339 selectorStyle.TrackViewState ();
342 return selectorStyle;
346 [DefaultValue(">")]
348 [WebSysDescription ("")]
349 [WebCategory ("Appearance")]
350 public string SelectWeekText {
351 get { return ViewState.GetString ("SelectWeekText", ">"); }
352 set { ViewState ["SelectWeekText"] = value; }
356 [WebSysDescription ("")]
357 [WebCategory ("Appearance")]
358 public bool ShowDayHeader {
359 get { return ViewState.GetBool ("ShowDayHeader", true); }
360 set { ViewState ["ShowDayHeader"] = value; }
363 [DefaultValue(false)]
364 [WebSysDescription ("")]
365 [WebCategory ("Appearance")]
366 public bool ShowGridLines {
367 get { return ViewState.GetBool ("ShowGridLines", false); }
368 set { ViewState ["ShowGridLines"] = value; }
372 [WebSysDescription ("")]
373 [WebCategory ("Appearance")]
374 public bool ShowNextPrevMonth {
375 get { return ViewState.GetBool ("ShowNextPrevMonth", true); }
376 set { ViewState ["ShowNextPrevMonth"] = value; }
380 [WebSysDescription ("")]
381 [WebCategory ("Appearance")]
382 public bool ShowTitle {
383 get { return ViewState.GetBool ("ShowTitle", true); }
384 set { ViewState ["ShowTitle"] = value; }
387 [DefaultValue(TitleFormat.MonthYear)]
388 [WebSysDescription ("")]
389 [WebCategory ("Appearance")]
390 public TitleFormat TitleFormat {
391 get { return (TitleFormat) ViewState.GetInt ("TitleFormat", (int) TitleFormat.MonthYear); }
394 if (value != TitleFormat.Month && value != TitleFormat.MonthYear) {
395 throw new ArgumentOutOfRangeException ("The specified title format is not one of the TitleFormat values.");
398 ViewState ["TitleFormat"] = value;
402 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
403 [NotifyParentProperty(true)]
404 [PersistenceMode(PersistenceMode.InnerProperty)]
405 [WebSysDescription ("")]
406 [WebCategory ("Style")]
407 public TableItemStyle TitleStyle {
409 if (titleStyle == null) {
410 titleStyle = new TableItemStyle ();
411 if (IsTrackingViewState)
412 titleStyle.TrackViewState ();
420 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
421 [NotifyParentProperty(true)]
422 [PersistenceMode(PersistenceMode.InnerProperty)]
423 [WebSysDescription ("")]
424 [WebCategory ("Style")]
425 public TableItemStyle TodayDayStyle {
427 if (todayDayStyle == null) {
428 todayDayStyle = new TableItemStyle ();
429 if (IsTrackingViewState)
430 todayDayStyle.TrackViewState ();
433 return todayDayStyle;
438 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
439 [WebSysDescription ("")]
440 [WebCategory ("Style")]
441 public DateTime TodaysDate {
443 object obj = ViewState ["TodaysDate"];
446 return (DateTime) obj;
451 set { ViewState ["TodaysDate"] = value.Date; }
454 [DefaultValue (true)]
455 [WebSysDescription ("")]
456 [WebCategoryAttribute ("Accessibility")]
457 public virtual bool UseAccessibleHeader {
458 get { return ViewState.GetBool ("UseAccessibleHeader", true); }
459 set { ViewState ["UseAccessibleHeader"] = value; }
463 [DefaultValue("1/1/0001 12:00:00 AM")]
464 [WebSysDescription ("")]
465 [WebCategory ("Style")]
466 public DateTime VisibleDate {
468 object obj = ViewState ["VisibleDate"];
471 return (DateTime) obj;
473 return DateTime.MinValue;
476 set { ViewState ["VisibleDate"] = value.Date; }
479 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
480 [NotifyParentProperty(true)]
481 [PersistenceMode(PersistenceMode.InnerProperty)]
482 [WebSysDescription ("")]
483 [WebCategory ("Style")]
484 public TableItemStyle WeekendDayStyle {
486 if (weekendDayStyle == null) {
487 weekendDayStyle = new TableItemStyle ();
488 if (IsTrackingViewState)
489 weekendDayStyle.TrackViewState ();
492 return weekendDayStyle;
495 public override bool SupportsDisabledAttribute {
496 get { return RenderingCompatibilityLessThan40; }
498 // Private properties
499 DateTimeFormatInfo DateInfo {
501 if (dateInfo == null)
502 dateInfo = Thread.CurrentThread.CurrentCulture.DateTimeFormat;
508 DateTime DisplayDate {
510 DateTime dateTime = VisibleDate;
511 if (dateTime == DateTime.MinValue) // If visibledate is still the default value
512 dateTime = TodaysDate;
518 DayOfWeek DisplayFirstDayOfWeek {
520 if (FirstDayOfWeek != FirstDayOfWeek.Default)
521 return (DayOfWeek) FirstDayOfWeek;
523 return (DayOfWeek) DateInfo.FirstDayOfWeek;
527 protected override ControlCollection CreateControlCollection ()
529 return base.CreateControlCollection ();
532 protected bool HasWeekSelectors (CalendarSelectionMode selectionMode)
534 if (selectionMode == CalendarSelectionMode.DayWeek || selectionMode == CalendarSelectionMode.DayWeekMonth)
540 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
542 RaisePostBackEvent (eventArgument);
545 protected virtual void RaisePostBackEvent (string eventArgument)
547 ValidateEvent (UniqueID, eventArgument);
548 if (eventArgument.Length < 1)
551 if (eventArgument[0] == 'V') { // Goes to Next or Previous month
552 DateTime prev = VisibleDate;
553 int days = Int32.Parse (eventArgument.Substring (1));
554 DateTime dt = GetGlobalCalendar().AddDays (dateZenith, days);
556 OnVisibleMonthChanged (VisibleDate, prev);
560 if (eventArgument[0] == 'R') { // Selects a range of dates
561 string num, date, days;
562 num = eventArgument.Substring (1);
563 days = num.Substring (num.Length - 2, 2);
564 date = num.Substring (0, num.Length - 2);
565 DateTime d = GetGlobalCalendar().AddDays (dateZenith, Int32.Parse (date));
566 SelectedDates.SelectRange (d, d.AddDays (Int32.Parse (days)));
567 OnSelectionChanged ();
571 // Selects a single day
572 int daysFromZenith = Int32.Parse (eventArgument);
573 DateTime day = GetGlobalCalendar().AddDays (dateZenith, daysFromZenith);
574 SelectedDates.SelectRange (day, day);
575 OnSelectionChanged ();
578 protected override void LoadViewState (object savedState)
580 object [] states = (object []) savedState;
582 if (states [0] != null)
583 base.LoadViewState (states [0]);
585 if (states [1] != null)
586 DayHeaderStyle.LoadViewState (states [1]);
588 if (states [2] != null)
589 DayStyle.LoadViewState (states [2]);
591 if (states [3] != null)
592 NextPrevStyle.LoadViewState (states [3]);
594 if (states [4] != null)
595 OtherMonthDayStyle.LoadViewState (states [4]);
597 if (states [5] != null)
598 SelectedDayStyle.LoadViewState (states [5]);
600 if (states [6] != null)
601 TitleStyle.LoadViewState (states [6]);
603 if (states [7] != null)
604 TodayDayStyle.LoadViewState (states [7]);
606 if (states [8] != null)
607 SelectorStyle.LoadViewState (states [8]);
609 if (states [9] != null)
610 WeekendDayStyle.LoadViewState (states [9]);
612 ArrayList array = (ArrayList) ViewState ["SelectedDates"];
615 selectedDatesCollection = new SelectedDatesCollection (dateList);
619 protected virtual void OnDayRender (TableCell cell, CalendarDay day)
621 DayRenderEventHandler eh = (DayRenderEventHandler) (Events [DayRenderEvent]);
625 eh (this, new DayRenderEventArgs (cell, day, page.ClientScript.GetPostBackClientHyperlink (this, GetDaysFromZenith (day.Date).ToString (), true)));
627 eh (this, new DayRenderEventArgs (cell, day));
631 protected internal override void OnPreRender (EventArgs e)
633 base.OnPreRender (e);
636 protected virtual void OnSelectionChanged ()
638 EventHandler eh = (EventHandler) (Events [SelectionChangedEvent]);
640 eh (this, EventArgs.Empty);
643 protected virtual void OnVisibleMonthChanged (DateTime newDate, DateTime previousDate)
645 MonthChangedEventHandler eh = (MonthChangedEventHandler) (Events [VisibleMonthChangedEvent]);
647 eh (this, new MonthChangedEventArgs (newDate, previousDate));
650 protected internal override void Render (HtmlTextWriter writer)
652 TableStyle ts = new TableStyle ();
653 ts.CellSpacing = CellSpacing;
654 ts.CellPadding = CellPadding;
656 if (ControlStyleCreated)
657 ts.CopyFrom (ControlStyle);
659 ts.GridLines = GridLines.Both;
660 ts.AddAttributesToRender (writer);
661 writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
662 writer.RenderBeginTag (HtmlTextWriterTag.Table);
664 if (!String.IsNullOrEmpty (Caption))
665 WriteCaption (writer);
667 bool enabled = IsEnabled;
670 WriteTitle (writer, enabled);
673 WriteDayHeader (writer, enabled);
675 WriteDays (writer, enabled);
677 writer.RenderEndTag ();
680 protected override object SaveViewState ()
682 object [] states = new object [10];
684 if (dayHeaderStyle != null)
685 states [1] = dayHeaderStyle.SaveViewState ();
687 if (dayStyle != null)
688 states [2] = dayStyle.SaveViewState ();
690 if (nextPrevStyle != null)
691 states [3] = nextPrevStyle.SaveViewState ();
693 if (otherMonthDayStyle != null)
694 states [4] = otherMonthDayStyle.SaveViewState ();
696 if (selectedDayStyle != null)
697 states [5] = selectedDayStyle.SaveViewState ();
699 if (titleStyle != null)
700 states [6] = titleStyle.SaveViewState ();
702 if (todayDayStyle != null)
703 states [7] =todayDayStyle.SaveViewState ();
705 if (selectorStyle != null)
706 states [8] = selectorStyle.SaveViewState ();
708 if (weekendDayStyle != null)
709 states [9] = weekendDayStyle.SaveViewState ();
711 if (SelectedDates.Count > 0) {
712 ViewState ["SelectedDates"] = dateList;
715 states [0] = base.SaveViewState ();
717 for (int i = 0; i < states.Length; i++) {
718 if (states [i] != null)
725 protected override void TrackViewState ()
727 base.TrackViewState ();
729 if (dayHeaderStyle != null)
730 dayHeaderStyle.TrackViewState ();
732 if (dayStyle != null)
733 dayStyle.TrackViewState ();
735 if (nextPrevStyle != null)
736 nextPrevStyle.TrackViewState ();
738 if (otherMonthDayStyle != null)
739 otherMonthDayStyle.TrackViewState ();
741 if (selectedDayStyle != null)
742 selectedDayStyle.TrackViewState ();
744 if (titleStyle != null)
745 titleStyle.TrackViewState ();
747 if (todayDayStyle != null)
748 todayDayStyle.TrackViewState ();
750 if (selectorStyle != null)
751 selectorStyle.TrackViewState ();
753 if (weekendDayStyle != null)
754 weekendDayStyle.TrackViewState ();
760 void WriteDayHeader (HtmlTextWriter writer, bool enabled)
764 i = first = (int) (DisplayFirstDayOfWeek);
768 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
770 if (SelectionMode == CalendarSelectionMode.DayWeek) {
771 cell = new TableCell();
772 cell.HorizontalAlign = HorizontalAlign.Center;
773 cell.ApplyStyle (DayHeaderStyle);
776 cell.RenderBeginTag (writer);
777 cell.RenderEndTag (writer);
779 if (SelectionMode == CalendarSelectionMode.DayWeekMonth) {
780 TableCell selector = new TableCell ();
781 selector.ApplyStyle (SelectorStyle);
782 selector.HorizontalAlign = HorizontalAlign.Center;
784 DateTime date = new DateTime (DisplayDate.Year, DisplayDate.Month, 1); // first date
785 int days = DateTime.DaysInMonth (DisplayDate.Year, DisplayDate.Month);
787 selector.RenderBeginTag (writer);
788 writer.Write (BuildLink ("R" + GetDaysFromZenith (date) + days, SelectMonthText, DayHeaderStyle.ForeColor, enabled));
789 selector.RenderEndTag (writer);
793 DateTimeFormatInfo dti = DateInfo;
795 DayOfWeek dayOfWeek = (DayOfWeek) i;
796 dayName = dti.GetDayName (dayOfWeek);
798 if (UseAccessibleHeader) {
799 writer.AddAttribute (HtmlTextWriterAttribute.Abbr, dayName);
800 writer.AddAttribute (HtmlTextWriterAttribute.Scope, "col", false);
801 cell = new TableHeaderCell();
803 cell = new TableCell();
805 cell.HorizontalAlign = HorizontalAlign.Center;
806 cell.ApplyStyle (DayHeaderStyle);
808 cell.RenderBeginTag (writer);
810 switch (DayNameFormat) {
811 case DayNameFormat.FirstLetter:
812 dayName = dayName.Substring (0, 1);
814 case DayNameFormat.FirstTwoLetters:
815 dayName = dayName.Substring (0, 2);
817 case DayNameFormat.Shortest:
818 dayName = dti.GetShortestDayName (dayOfWeek);
820 case DayNameFormat.Full:
822 case DayNameFormat.Short:
824 dayName = dti.GetAbbreviatedDayName (dayOfWeek);
828 writer.Write (dayName);
829 cell.RenderEndTag (writer);
831 if (i >= daysInAWeek - 1)
840 writer.RenderEndTag ();
843 void WriteDay (DateTime date, HtmlTextWriter writer, bool enabled)
845 TableItemStyle style = new TableItemStyle ();
846 TableCell cell = new TableCell ();
848 CalendarDay day = new CalendarDay (date,
849 IsWeekEnd (date.DayOfWeek),
850 date == TodaysDate, SelectedDates.Contains (date),
851 GetGlobalCalendar ().GetMonth (DisplayDate) != GetGlobalCalendar ().GetMonth (date),
852 date.Day.ToString ());
854 day.IsSelectable = SelectionMode != CalendarSelectionMode.None;
855 cell.HorizontalAlign = HorizontalAlign.Center;
856 cell.Width = Unit.Percentage (GetCellWidth ());
858 LiteralControl lit = new LiteralControl (day.DayNumberText);
859 cell.Controls.Add (lit);
861 OnDayRender (cell, day);
863 if (dayStyle != null && !dayStyle.IsEmpty)
864 style.CopyFrom (dayStyle);
866 if (day.IsWeekend && weekendDayStyle != null && !weekendDayStyle.IsEmpty)
867 style.CopyFrom (weekendDayStyle);
869 if (day.IsToday && todayDayStyle != null && !todayDayStyle.IsEmpty)
870 style.CopyFrom (todayDayStyle);
872 if (day.IsOtherMonth && otherMonthDayStyle != null && !otherMonthDayStyle.IsEmpty)
873 style.CopyFrom (otherMonthDayStyle);
875 if (enabled && day.IsSelected) {
876 style.BackColor = Color.Silver;
877 style.ForeColor = Color.White;
878 if (selectedDayStyle != null && !selectedDayStyle.IsEmpty)
879 style.CopyFrom (selectedDayStyle);
882 cell.ApplyStyle (style);
884 lit.Text = BuildLink (GetDaysFromZenith (date).ToString (), day.DayNumberText,
885 cell.ForeColor, enabled && day.IsSelectable);
887 cell.RenderControl (writer);
890 void WriteDays (HtmlTextWriter writer, bool enabled)
892 DateTime date = new DateTime (DisplayDate.Year, DisplayDate.Month, 1); // first date
894 TableCell selectorCell = null;
897 // Goes backwards until we find the date of that is begining of the week
898 for (n = 0; n < daysInAWeek; n++) {
899 if (date.DayOfWeek == DisplayFirstDayOfWeek)
902 date = GetGlobalCalendar().AddDays (date, -1);
904 /* if the start date is the first day of the week, we need to shift backward one more week */
906 date = GetGlobalCalendar().AddDays (date, -1 * daysInAWeek);
908 lastDate = GetGlobalCalendar().AddDays (date, 6 * daysInAWeek); // Always six weeks per months
911 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
913 if (HasWeekSelectors (SelectionMode)) { // Week selector
914 if (selectorCell == null) {
915 selectorCell = new TableCell ();
916 selectorCell.ApplyStyle (SelectorStyle);
917 selectorCell.HorizontalAlign = HorizontalAlign.Center;
918 selectorCell.Width = Unit.Percentage (GetCellWidth ());
921 selectorCell.RenderBeginTag (writer);
922 writer.Write (BuildLink ("R" + GetDaysFromZenith (date) + "07", SelectWeekText, selectorCell.ForeColor, enabled));
923 selectorCell.RenderEndTag (writer);
926 for (int i = 0; i < daysInAWeek; i++) {
927 WriteDay (date, writer, enabled);
928 date = GetGlobalCalendar().AddDays (date, 1);
931 writer.RenderEndTag ();
932 if (date >= lastDate)
937 string BuildLink (string arg, string text, Color foreColor, bool hasLink)
939 StringBuilder str = new StringBuilder ();
942 hasLink = (page != null && hasLink == true) ? true : false;
945 str.Append ("<a href=\"");
946 str.Append (page.ClientScript.GetPostBackClientHyperlink (this, arg, true));
950 if (!foreColor.IsEmpty)
953 if (ForeColor.IsEmpty)
959 str.Append (" style=\"color:" + ColorTranslator.ToHtml (clr));
966 return str.ToString ();
969 int GetDaysFromZenith (DateTime date)
971 TimeSpan span = date.Subtract (dateZenith);
975 void WriteCaption (HtmlTextWriter writer)
977 if (CaptionAlign != TableCaptionAlign.NotSet)
978 writer.AddAttribute (HtmlTextWriterAttribute.Align, CaptionAlign.ToString (Helpers.InvariantCulture));
980 writer.RenderBeginTag (HtmlTextWriterTag.Caption);
981 writer.Write (Caption);
982 writer.RenderEndTag ();
985 void WriteTitle (HtmlTextWriter writer, bool enabled)
987 TableCell cellNextPrev = null;
988 TableCell titleCell = new TableCell ();
989 Table tableTitle = new Table ();
991 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
993 titleCell.ColumnSpan = HasWeekSelectors (SelectionMode) ? 8 : 7;
995 if (titleStyle != null && !titleStyle.IsEmpty && !titleStyle.BackColor.IsEmpty)
996 titleCell.BackColor = titleStyle.BackColor;
998 titleCell.BackColor = Color.Silver;
1000 titleCell.RenderBeginTag (writer);
1003 tableTitle.Width = Unit.Percentage (100);
1004 if (titleStyle != null && !titleStyle.IsEmpty)
1005 tableTitle.ApplyStyle (titleStyle);
1007 tableTitle.RenderBeginTag (writer);
1008 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1010 if (ShowNextPrevMonth) { // Previous Table Data
1011 cellNextPrev = new TableCell ();
1012 cellNextPrev.ApplyStyle (nextPrevStyle);
1013 cellNextPrev.Width = Unit.Percentage (15);
1015 DateTime date = GetGlobalCalendar().AddMonths (DisplayDate, - 1);
1016 date = GetGlobalCalendar ().AddDays (date, -date.Day + 1);
1017 cellNextPrev.RenderBeginTag (writer);
1018 writer.Write (BuildLink ("V" + GetDaysFromZenith (date), GetNextPrevFormatText (date, false), cellNextPrev.ForeColor, enabled));
1019 cellNextPrev.RenderEndTag (writer);
1022 // Current Month Table Data
1024 DateTimeFormatInfo dti = DateInfo;
1026 TableCell cellMonth = new TableCell ();
1027 cellMonth.Width = Unit.Percentage (70);
1028 cellMonth.HorizontalAlign = HorizontalAlign.Center;
1030 cellMonth.RenderBeginTag (writer);
1032 if (TitleFormat == TitleFormat.MonthYear)
1033 str = DisplayDate.ToString (dti.YearMonthPattern, dti);
1035 str = dti.GetMonthName (GetGlobalCalendar ().GetMonth (DisplayDate));
1038 cellMonth.RenderEndTag (writer);
1041 if (ShowNextPrevMonth) { // Next Table Data
1042 DateTime date = GetGlobalCalendar().AddMonths (DisplayDate, + 1);
1043 date = GetGlobalCalendar ().AddDays (date, -date.Day + 1);
1045 cellNextPrev.HorizontalAlign = HorizontalAlign.Right;
1046 cellNextPrev.RenderBeginTag (writer);
1047 writer.Write (BuildLink ("V" + GetDaysFromZenith (date), GetNextPrevFormatText (date, true), cellNextPrev.ForeColor, enabled));
1048 cellNextPrev.RenderEndTag (writer);
1051 writer.RenderEndTag ();
1052 tableTitle.RenderEndTag (writer);
1053 titleCell.RenderEndTag (writer);
1054 writer.RenderEndTag (); //tr
1057 string GetNextPrevFormatText (DateTime date, bool next)
1060 DateTimeFormatInfo dti = DateInfo;
1061 switch (NextPrevFormat) {
1062 case NextPrevFormat.FullMonth:
1063 text = dti.GetMonthName (GetGlobalCalendar ().GetMonth (date));
1065 case NextPrevFormat.ShortMonth:
1066 text = dti.GetAbbreviatedMonthName (GetGlobalCalendar ().GetMonth (date));
1068 case NextPrevFormat.CustomText:
1070 text = ((next) ? NextMonthText : PrevMonthText);
1077 bool IsWeekEnd (DayOfWeek day)
1079 return (day == DayOfWeek.Saturday || day == DayOfWeek.Sunday);
1082 double GetCellWidth ()
1084 return HasWeekSelectors (SelectionMode) ? 100/8 : 100/7;
1087 System.Globalization.Calendar GetGlobalCalendar ()
1089 return DateTimeFormatInfo.CurrentInfo.Calendar;
1092 [WebSysDescription ("")]
1093 [WebCategory ("Action")]
1094 public event DayRenderEventHandler DayRender {
1095 add { Events.AddHandler (DayRenderEvent, value); }
1096 remove { Events.RemoveHandler (DayRenderEvent, value); }
1099 [WebSysDescription ("")]
1100 [WebCategory ("Action")]
1101 public event EventHandler SelectionChanged {
1102 add { Events.AddHandler (SelectionChangedEvent, value); }
1103 remove { Events.RemoveHandler (SelectionChangedEvent, value); }
1106 [WebSysDescription ("")]
1107 [WebCategory ("Action")]
1108 public event MonthChangedEventHandler VisibleMonthChanged {
1109 add { Events.AddHandler (VisibleMonthChangedEvent, value); }
1110 remove { Events.RemoveHandler (VisibleMonthChangedEvent, value); }