Calendar.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / xsp / System / Web / UI / WebControls / Calendar.cs / 1 / Calendar.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls { 
    using System.Threading; 
    using System.Globalization;
    using System.ComponentModel; 
    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.Util; 
    using System.Collections;
    using System.ComponentModel.Design; 
    using System.Drawing; 
    using System.Text;
 
    using System.IO;
    using System.Reflection;
    using System.Security.Permissions;
 

 
    ///  
    ///    Displays a one-month calendar and allows the user to
    ///       view and select a specific day, week, or month. 
    /// 
    [
    ControlValueProperty("SelectedDate", typeof(DateTime), "1/1/0001"),
    DataBindingHandler("System.Web.UI.Design.WebControls.CalendarDataBindingHandler, " + AssemblyRef.SystemDesign), 
    DefaultEvent("SelectionChanged"),
    DefaultProperty("SelectedDate"), 
    Designer("System.Web.UI.Design.WebControls.CalendarDesigner, " + AssemblyRef.SystemDesign), 
    SupportsEventValidation
    ] 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class Calendar : WebControl, IPostBackEventHandler {
 
        private static readonly object EventDayRender = new object();
        private static readonly object EventSelectionChanged = new object(); 
        private static readonly object EventVisibleMonthChanged = new object(); 

        private TableItemStyle titleStyle; 
        private TableItemStyle nextPrevStyle;
        private TableItemStyle dayHeaderStyle;
        private TableItemStyle selectorStyle;
        private TableItemStyle dayStyle; 
        private TableItemStyle otherMonthDayStyle;
        private TableItemStyle todayDayStyle; 
        private TableItemStyle selectedDayStyle; 
        private TableItemStyle weekendDayStyle;
        private string defaultButtonColorText; 

        private static readonly Color DefaultForeColor = Color.Black;
        private Color defaultForeColor;
 
        private ArrayList dateList;
        private SelectedDatesCollection selectedDates; 
        private Globalization.Calendar threadCalendar; 
        private DateTime minSupportedDate;
        private DateTime maxSupportedDate; 
#if DEBUG
        private bool threadCalendarInitialized;
#endif
 
        private const string SELECT_RANGE_COMMAND = "R";
        private const string NAVIGATE_MONTH_COMMAND = "V"; 
 
        private static DateTime baseDate = new DateTime(2000, 1, 1);
 
        private const int STYLEMASK_DAY = 16;
        private const int STYLEMASK_UNIQUE = 15;
        private const int STYLEMASK_SELECTED = 8;
        private const int STYLEMASK_TODAY = 4; 
        private const int STYLEMASK_OTHERMONTH = 2;
        private const int STYLEMASK_WEEKEND = 1; 
        private const string ROWBEGINTAG = ""; 
        private const string ROWENDTAG = "";
 
        // Cache commonly used strings. This improves performance and memory usage.
        private const int cachedNumberMax = 31;
        private static readonly string[] cachedNumbers = new string [] {
                  "0",  "1",   "2",   "3",   "4",   "5",   "6", 
                  "7",  "8",   "9",  "10",  "11",  "12",  "13",
                 "14", "15",  "16",  "17",  "18",  "19",  "20", 
                 "21", "22",  "23",  "24",  "25",  "26",  "27", 
                 "28", "29",  "30",  "31",
        }; 


        /// 
        /// Initializes a new instance of the  class. 
        /// 
        public Calendar() : base(HtmlTextWriterTag.Table) { 
        } 

 
        [
        Localizable(true),
        DefaultValue(""),
        WebCategory("Accessibility"), 
        WebSysDescription(SR.Calendar_Caption)
        ] 
        public virtual string Caption { 
            get {
                string s = (string)ViewState["Caption"]; 
                return (s != null) ? s : String.Empty;
            }
            set {
                ViewState["Caption"] = value; 
            }
        } 
 

        [ 
        DefaultValue(TableCaptionAlign.NotSet),
        WebCategory("Accessibility"),
        WebSysDescription(SR.WebControl_CaptionAlign)
        ] 
        public virtual TableCaptionAlign CaptionAlign {
            get { 
                object o = ViewState["CaptionAlign"]; 
                return (o != null) ? (TableCaptionAlign)o : TableCaptionAlign.NotSet;
            } 
            set {
                if ((value < TableCaptionAlign.NotSet) ||
                    (value > TableCaptionAlign.Right)) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["CaptionAlign"] = value; 
            } 
        }
 

        /// 
        ///    Gets or sets the amount of space between cells.
        ///  
        [
        WebCategory("Layout"), 
        DefaultValue(2), 
        WebSysDescription(SR.Calendar_CellPadding)
        ] 
        public int CellPadding {
            get {
                object o = ViewState["CellPadding"];
                return((o == null) ? 2 : (int)o); 
            }
            set { 
                if (value < - 1 ) { 
                    throw new ArgumentOutOfRangeException("value");
                } 
                ViewState["CellPadding"] = value;
            }
        }
 

        ///  
        ///    Gets or sets the amount of space between the contents of a cell 
        ///       and the cell's border.
        ///  
        [
        WebCategory("Layout"),
        DefaultValue(0),
        WebSysDescription(SR.Calendar_CellSpacing) 
        ]
        public int CellSpacing { 
            get { 
                object o = ViewState["CellSpacing"];
                return((o == null) ?  0 : (int)o); 
            }
            set {
                if (value < -1 ) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["CellSpacing"] = (int)value; 
            } 
        }
 

        /// 
        ///     Gets the style property of the day-of-the-week header. This property is read-only.
        ///  
        [
        WebCategory("Styles"), 
        WebSysDescription(SR.Calendar_DayHeaderStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle DayHeaderStyle {
            get { 
                if (dayHeaderStyle == null) {
                    dayHeaderStyle = new TableItemStyle(); 
                    if (IsTrackingViewState) 
                        ((IStateManager)dayHeaderStyle).TrackViewState();
                } 
                return dayHeaderStyle;
            }
        }
 

        ///  
        ///    Gets or sets 
        ///       the format for the names of days.
        ///  
        [
        WebCategory("Appearance"),
        DefaultValue(DayNameFormat.Short),
        WebSysDescription(SR.Calendar_DayNameFormat) 
        ]
        public DayNameFormat DayNameFormat { 
            get { 
                object dnf = ViewState["DayNameFormat"];
                return((dnf == null) ? DayNameFormat.Short : (DayNameFormat)dnf); 
            }
            set {
                if (value < DayNameFormat.Full || value > DayNameFormat.Shortest) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["DayNameFormat"] = value; 
            } 
        }
 

        /// 
        ///     Gets the style properties for the days. This property is read-only.
        ///  
        [
        WebCategory("Styles"), 
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_DayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle DayStyle { 
            get {
                if (dayStyle == null) { 
                    dayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)dayStyle).TrackViewState(); 
                }
                return dayStyle;
            }
        } 

 
        ///  
        ///     Gets
        ///       or sets the day of the week to display in the calendar's first 
        ///       column.
        /// 
        [
        WebCategory("Appearance"), 
        DefaultValue(FirstDayOfWeek.Default),
        WebSysDescription(SR.Calendar_FirstDayOfWeek) 
        ] 
        public FirstDayOfWeek FirstDayOfWeek {
            get { 
                object o = ViewState["FirstDayOfWeek"];
                return((o == null) ? FirstDayOfWeek.Default : (FirstDayOfWeek)o);
            }
            set { 
                if (value < FirstDayOfWeek.Sunday || value > FirstDayOfWeek.Default) {
                    throw new ArgumentOutOfRangeException("value"); 
                } 

                ViewState["FirstDayOfWeek"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets the text shown for the next month 
        ///       navigation hyperlink if the  property is set to 
        ///    .
        ///  
        [
        Localizable(true),
        WebCategory("Appearance"),
        DefaultValue(">"), 
        WebSysDescription(SR.Calendar_NextMonthText)
        ] 
        public string NextMonthText { 
            get {
                object s = ViewState["NextMonthText"]; 
                return((s == null) ? ">" : (String) s);
            }
            set {
                ViewState["NextMonthText"] = value; 
            }
        } 
 

        ///  
        ///    Gets or sets the format of the next and previous month hyperlinks in the
        ///       title.
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(NextPrevFormat.CustomText), 
        WebSysDescription(SR.Calendar_NextPrevFormat) 
        ]
        public NextPrevFormat NextPrevFormat { 
            get {
                object npf = ViewState["NextPrevFormat"];
                return((npf == null) ? NextPrevFormat.CustomText : (NextPrevFormat)npf);
            } 
            set {
                if (value < NextPrevFormat.CustomText || value > NextPrevFormat.FullMonth) { 
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["NextPrevFormat"] = value; 
            }
        }

 
        /// 
        ///     Gets the style properties for the next/previous month navigators. This property is 
        ///       read-only. 
        /// 
        [ 
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_NextPrevStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle NextPrevStyle { 
            get {
                if (nextPrevStyle == null) { 
                    nextPrevStyle = new TableItemStyle();
                    if (IsTrackingViewState)
                        ((IStateManager)nextPrevStyle).TrackViewState();
                } 
                return nextPrevStyle;
            } 
        } 

 

        /// 
        ///    Gets the style properties for the days from the months preceding and following the current month.
        ///       This property is read-only. 
        /// 
        [ 
        WebCategory("Styles"), 
        DefaultValue(null),
        WebSysDescription(SR.Calendar_OtherMonthDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle OtherMonthDayStyle {
            get { 
                if (otherMonthDayStyle == null) { 
                    otherMonthDayStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)otherMonthDayStyle).TrackViewState();

                }
                return otherMonthDayStyle; 
            }
        } 
 

        ///  
        ///    Gets or sets the text shown for the previous month
        ///       navigation hyperlink if the  property is set to
        ///    
        ///    . 
        /// 
        [ 
        Localizable(true), 
        WebCategory("Appearance"),
        DefaultValue("<"), 
        WebSysDescription(SR.Calendar_PrevMonthText)
        ]
        public string PrevMonthText {
            get { 
                object s = ViewState["PrevMonthText"];
                return((s == null) ? "<" : (String) s); 
            } 
            set {
                ViewState["PrevMonthText"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets the date that is currently selected 
        ///       date. 
        /// 
        [ 
        Bindable(true, BindingDirection.TwoWay),
        DefaultValue(typeof(DateTime), "1/1/0001"),
        WebSysDescription(SR.Calendar_SelectedDate)
        ] 
        public DateTime SelectedDate {
            get { 
                if (SelectedDates.Count == 0) { 
                    return DateTime.MinValue;
                } 
                return SelectedDates[0];
            }
            set {
                if (value == DateTime.MinValue) { 
                    SelectedDates.Clear();
                } 
                else { 
                    SelectedDates.SelectRange(value, value);
                } 
            }
        }

 
        /// 
        /// Gets a collection of  objects representing days selected on the . This 
        ///    property is read-only. 
        /// 
        [ 
        Browsable(false),
        WebSysDescription(SR.Calendar_SelectedDates),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public SelectedDatesCollection SelectedDates {
            get { 
                if (selectedDates == null) { 
                    if (dateList == null) {
                        dateList = new ArrayList(); 
                    }
                    selectedDates = new SelectedDatesCollection(dateList);
                }
                return selectedDates; 
            }
        } 
 

        ///  
        ///    Gets the style properties for the selected date. This property is read-only.
        /// 
        [
        WebCategory("Styles"), 
        DefaultValue(null),
        WebSysDescription(SR.Calendar_SelectedDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle SelectedDayStyle {
            get {
                if (selectedDayStyle == null) { 
                    selectedDayStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)selectedDayStyle).TrackViewState(); 
                }
                return selectedDayStyle; 
            }
        }

 
        /// 
        ///    Gets or sets the date selection capabilities on the 
        ///     
        ///    to allow the user to select a day, week, or month.
        ///  
        [
        WebCategory("Behavior"),
        DefaultValue(CalendarSelectionMode.Day),
        WebSysDescription(SR.Calendar_SelectionMode) 
        ]
        public CalendarSelectionMode SelectionMode { 
            get { 
                object csm = ViewState["SelectionMode"];
                return((csm == null) ? CalendarSelectionMode.Day : (CalendarSelectionMode)csm); 
            }
            set {
                if (value < CalendarSelectionMode.None || value > CalendarSelectionMode.DayWeekMonth) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["SelectionMode"] = value; 
            } 
        }
 

        /// 
        ///    Gets or sets the text shown for the month selection in
        ///       the selector column if  is 
        ///    .
        ///  
        [ 
        Localizable(true),
        WebCategory("Appearance"), 
        DefaultValue(">>"),
        WebSysDescription(SR.Calendar_SelectMonthText)
        ]
        public string SelectMonthText { 
            get {
                object s = ViewState["SelectMonthText"]; 
                return((s == null) ? ">>" : (String) s); 
            }
            set { 
                ViewState["SelectMonthText"] = value;
            }
        }
 

        ///  
        ///     Gets the style properties for the week and month selectors. This property is read-only. 
        /// 
        [ 
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_SelectorStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle SelectorStyle { 
            get {
                if (selectorStyle == null) { 
                    selectorStyle = new TableItemStyle();
                    if (IsTrackingViewState)
                        ((IStateManager)selectorStyle).TrackViewState();
                } 
                return selectorStyle;
            } 
        } 

        ///  
        ///    Gets or sets the text shown for the week selection in
        ///       the selector column if  is
        ///    or
        ///    . 
        /// 
        [ 
        Localizable(true), 
        WebCategory("Appearance"),
        DefaultValue(">"), 
        WebSysDescription(SR.Calendar_SelectWeekText)
        ]
        public string SelectWeekText {
            get { 
                object s = ViewState["SelectWeekText"];
                return((s == null) ? ">" : (String) s); 
            } 
            set {
                ViewState["SelectWeekText"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets 
        ///       a value indicating whether the days of the week are displayed. 
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(true),
        WebSysDescription(SR.Calendar_ShowDayHeader)
        ] 
        public bool ShowDayHeader {
            get { 
                object b = ViewState["ShowDayHeader"]; 
                return((b == null) ? true : (bool)b);
            } 
            set {
                ViewState["ShowDayHeader"] = value;
            }
        } 

 
        ///  
        ///    Gets or set
        ///       a value indicating whether days on the calendar are displayed with a border. 
        /// 
        [
        WebCategory("Appearance"),
        DefaultValue(false), 
        WebSysDescription(SR.Calendar_ShowGridLines)
        ] 
        public bool ShowGridLines { 
            get {
                object b= ViewState["ShowGridLines"]; 
                return((b == null) ? false : (bool)b);
            }
            set {
                ViewState["ShowGridLines"] = value; 
            }
        } 
 

        ///  
        /// Gets or sets a value indicating whether the 
        /// displays the next and pervious month
        /// hyperlinks in the title.
        ///  
        [
        WebCategory("Appearance"), 
        DefaultValue(true), 
        WebSysDescription(SR.Calendar_ShowNextPrevMonth)
        ] 
        public bool ShowNextPrevMonth {
            get {
                object b = ViewState["ShowNextPrevMonth"];
                return((b == null) ? true : (bool)b); 
            }
            set { 
                ViewState["ShowNextPrevMonth"] = value; 
            }
        } 


        /// 
        ///     Gets or 
        ///       sets a value indicating whether the title is displayed.
        ///  
        [ 
        WebCategory("Appearance"),
        DefaultValue(true), 
        WebSysDescription(SR.Calendar_ShowTitle)
        ]
        public bool ShowTitle {
            get { 
                object b = ViewState["ShowTitle"];
                return((b == null) ? true : (bool)b); 
            } 
            set {
                ViewState["ShowTitle"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets how the month name is formatted in the title 
        ///       bar. 
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(TitleFormat.MonthYear),
        WebSysDescription(SR.Calendar_TitleFormat)
        ] 
        public TitleFormat TitleFormat {
            get { 
                object tf = ViewState["TitleFormat"]; 
                return((tf == null) ? TitleFormat.MonthYear : (TitleFormat)tf);
            } 
            set {
                if (value < TitleFormat.Month || value > TitleFormat.MonthYear) {
                    throw new ArgumentOutOfRangeException("value");
                } 
                ViewState["TitleFormat"] = value;
            } 
        } 

 
        /// 
        /// Gets the style properties of the  title. This property is
        ///    read-only.
        ///  
        [
        WebCategory("Styles"), 
        WebSysDescription(SR.Calendar_TitleStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        public TableItemStyle TitleStyle {
            get { 
                if (titleStyle == null) {
                    titleStyle = new TableItemStyle(); 
                    if (IsTrackingViewState) 
                        ((IStateManager)titleStyle).TrackViewState();
                } 
                return titleStyle;
            }
        }
 

        ///  
        ///    Gets the style properties for today's date on the 
        ///    . This
        ///       property is read-only. 
        /// 
        [
        WebCategory("Styles"),
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_TodayDayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle TodayDayStyle {
            get {
                if (todayDayStyle == null) {
                    todayDayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)todayDayStyle).TrackViewState(); 
                } 
                return todayDayStyle;
            } 
        }


        ///  
        ///    Gets or sets the value to use as today's date.
        ///  
        [ 
        Browsable(false),
        WebSysDescription(SR.Calendar_TodaysDate), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public DateTime TodaysDate {
            get { 
                object o = ViewState["TodaysDate"];
                return((o == null) ? DateTime.Today : (DateTime)o); 
            } 
            set {
                ViewState["TodaysDate"] = value.Date; 
            }
        }

 
        [
        DefaultValue(true), 
        WebCategory("Accessibility"), 
        WebSysDescription(SR.Table_UseAccessibleHeader)
        ] 
        public virtual bool UseAccessibleHeader {
            get {
                object o = ViewState["UseAccessibleHeader"];
                return (o != null) ? (bool)o : true; 
            }
            set { 
                ViewState["UseAccessibleHeader"] = value; 
            }
        } 


        /// 
        ///    Gets or sets the date that specifies what month to display. The date can be 
        ///       be any date within the month.
        ///  
        [ 
        Bindable(true),
        DefaultValue(typeof(DateTime), "1/1/0001"), 
        WebSysDescription(SR.Calendar_VisibleDate)
        ]
        public DateTime VisibleDate {
            get { 
                object o = ViewState["VisibleDate"];
                return((o == null) ? DateTime.MinValue : (DateTime)o); 
            } 
            set {
                ViewState["VisibleDate"] = value.Date; 
            }
        }

 
        /// 
        ///    Gets the style properties for the displaying weekend dates. This property is 
        ///       read-only. 
        /// 
        [ 
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_WeekendDayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle WeekendDayStyle { 
            get {
                if (weekendDayStyle == null) { 
                    weekendDayStyle = new TableItemStyle();
                    if (IsTrackingViewState)
                        ((IStateManager)weekendDayStyle).TrackViewState();
                } 
                return weekendDayStyle;
            } 
        } 

 

        /// 
        /// Occurs when each day is created in teh control hierarchy for the .
        ///  
        [
        WebCategory("Action"), 
        WebSysDescription(SR.Calendar_OnDayRender) 
        ]
        public event DayRenderEventHandler DayRender { 
            add {
                Events.AddHandler(EventDayRender, value);
            }
            remove { 
                Events.RemoveHandler(EventDayRender, value);
            } 
        } 

 


        /// 
        ///    Occurs when the user clicks on a day, week, or month 
        ///       selector and changes the .
        ///  
        [ 
        WebCategory("Action"),
        WebSysDescription(SR.Calendar_OnSelectionChanged) 
        ]
        public event EventHandler SelectionChanged {
            add {
                Events.AddHandler(EventSelectionChanged, value); 
            }
            remove { 
                Events.RemoveHandler(EventSelectionChanged, value); 
            }
        } 



        ///  
        ///    Occurs when the
        ///       user clicks on the next or previous month  controls on the title. 
        ///  
        [
        WebCategory("Action"), 
        WebSysDescription(SR.Calendar_OnVisibleMonthChanged)
        ]
        public event MonthChangedEventHandler VisibleMonthChanged {
            add { 
                Events.AddHandler(EventVisibleMonthChanged, value);
            } 
            remove { 
                Events.RemoveHandler(EventVisibleMonthChanged, value);
            } 
        }

        // Methods
 

        ///  
        ///  
        private void ApplyTitleStyle(TableCell titleCell, Table titleTable, TableItemStyle titleStyle) {
            // apply affects that affect the whole background to the cell 
            if (titleStyle.BackColor != Color.Empty) {
                titleCell.BackColor = titleStyle.BackColor;
            }
            if (titleStyle.BorderColor != Color.Empty) { 
                titleCell.BorderColor = titleStyle.BorderColor;
            } 
            if (titleStyle.BorderWidth != Unit.Empty) { 
                titleCell.BorderWidth= titleStyle.BorderWidth;
            } 
            if (titleStyle.BorderStyle != BorderStyle.NotSet) {
                titleCell.BorderStyle = titleStyle.BorderStyle;
            }
            if (titleStyle.Height != Unit.Empty) { 
                titleCell.Height = titleStyle.Height;
            } 
            if (titleStyle.VerticalAlign != VerticalAlign.NotSet) { 
                titleCell.VerticalAlign = titleStyle.VerticalAlign;
            } 

            // apply affects that affect everything else to the table
            if (titleStyle.CssClass.Length > 0) {
                titleTable.CssClass = titleStyle.CssClass; 
            }
            else if (CssClass.Length > 0) { 
                titleTable.CssClass = CssClass; 
            }
 
            if (titleStyle.ForeColor != Color.Empty) {
                titleTable.ForeColor = titleStyle.ForeColor;
            }
            else if (ForeColor != Color.Empty) { 
                titleTable.ForeColor = ForeColor;
            } 
            titleTable.Font.CopyFrom(titleStyle.Font); 
            titleTable.Font.MergeWith(this.Font);
 
        }


        ///  
        /// 
        ///  
        protected override ControlCollection CreateControlCollection() { 
            return new InternalControlCollection(this);
        } 



        ///  
        /// 
        private DateTime EffectiveVisibleDate() { 
            DateTime visDate = VisibleDate; 
            if (visDate.Equals(DateTime.MinValue)) {
                visDate = TodaysDate; 
            }

            // VSWhidbey 366243
            if (IsMinSupportedYearMonth(visDate)) { 
                return minSupportedDate;
            } 
            else { 
                return threadCalendar.AddDays(visDate, -(threadCalendar.GetDayOfMonth(visDate) - 1));
            } 
        }


        ///  
        /// 
        private DateTime FirstCalendarDay(DateTime visibleDate) { 
            DateTime firstDayOfMonth = visibleDate; 

            // VSWhidbey 366243 
            if (IsMinSupportedYearMonth(firstDayOfMonth)) {
                return firstDayOfMonth;
            }
 
            int daysFromLastMonth = ((int)threadCalendar.GetDayOfWeek(firstDayOfMonth)) - NumericFirstDayOfWeek();
            // Always display at least one day from the previous month 
            if (daysFromLastMonth <= 0) { 
                daysFromLastMonth += 7;
            } 
            return threadCalendar.AddDays(firstDayOfMonth, -daysFromLastMonth);
        }

 
        /// 
        ///  
        private string GetCalendarButtonText(string eventArgument, string buttonText, string title, bool showLink, Color foreColor) { 
            if (showLink) {
                StringBuilder sb = new StringBuilder(); 
                sb.Append(""); 
                sb.Append(buttonText); 
                sb.Append("");
                return sb.ToString(); 
            }
            else {
                return buttonText;
            } 
        }
 
 
        /// 
        ///  
        private int GetDefinedStyleMask() {

            // Selected is always defined because it has default effects
            int styleMask = STYLEMASK_SELECTED; 

            if (dayStyle != null && !dayStyle.IsEmpty) 
                styleMask |= STYLEMASK_DAY; 
            if (todayDayStyle != null && !todayDayStyle.IsEmpty)
                styleMask |= STYLEMASK_TODAY; 
            if (otherMonthDayStyle != null && !otherMonthDayStyle.IsEmpty)
                styleMask |= STYLEMASK_OTHERMONTH;
            if (weekendDayStyle != null && !weekendDayStyle.IsEmpty)
                styleMask |= STYLEMASK_WEEKEND; 
            return styleMask;
        } 
 

        ///  
        /// 
        private string GetMonthName(int m, bool bFull) {
            if (bFull) {
                return DateTimeFormatInfo.CurrentInfo.GetMonthName(m); 
            }
            else { 
                return DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(m); 
            }
        } 


        /// 
        /// Determines if a  
        /// contains week selectors.
        ///  
        protected bool HasWeekSelectors(CalendarSelectionMode selectionMode) { 
            return(selectionMode == CalendarSelectionMode.DayWeek
                   || selectionMode == CalendarSelectionMode.DayWeekMonth); 
        }

        private bool IsTheSameYearMonth(DateTime date1, DateTime date2) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized);
#endif 
            return (threadCalendar.GetEra(date1) == threadCalendar.GetEra(date2) && 
                    threadCalendar.GetYear(date1) == threadCalendar.GetYear(date2) &&
                    threadCalendar.GetMonth(date1) == threadCalendar.GetMonth(date2)); 
        }

        private bool IsMinSupportedYearMonth(DateTime date) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized);
#endif 
            return IsTheSameYearMonth(minSupportedDate, date); 
        }
 
        private bool IsMaxSupportedYearMonth(DateTime date) {
#if DEBUG
            Debug.Assert(threadCalendarInitialized);
#endif 
            return IsTheSameYearMonth(maxSupportedDate, date);
        } 
 
        /// 
        ///  
        /// Loads a saved state of the . 
        /// 
        protected override void LoadViewState(object savedState) {
            if (savedState != null) { 
                object[] myState = (object[])savedState;
 
                if (myState[0] != null) 
                    base.LoadViewState(myState[0]);
                if (myState[1] != null) 
                    ((IStateManager)TitleStyle).LoadViewState(myState[1]);
                if (myState[2] != null)
                    ((IStateManager)NextPrevStyle).LoadViewState(myState[2]);
                if (myState[3] != null) 
                    ((IStateManager)DayStyle).LoadViewState(myState[3]);
                if (myState[4] != null) 
                    ((IStateManager)DayHeaderStyle).LoadViewState(myState[4]); 
                if (myState[5] != null)
                    ((IStateManager)TodayDayStyle).LoadViewState(myState[5]); 
                if (myState[6] != null)
                    ((IStateManager)WeekendDayStyle).LoadViewState(myState[6]);
                if (myState[7] != null)
                    ((IStateManager)OtherMonthDayStyle).LoadViewState(myState[7]); 
                if (myState[8] != null)
                    ((IStateManager)SelectedDayStyle).LoadViewState(myState[8]); 
                if (myState[9] != null) 
                    ((IStateManager)SelectorStyle).LoadViewState(myState[9]);
 
                ArrayList selDates = (ArrayList)ViewState["SD"];
                if (selDates != null) {
                    dateList = selDates;
                    selectedDates = null;   // reset wrapper collection 
                }
 
            } 
        }
 

        /// 
        /// 
        ///    Marks the starting point to begin tracking and saving changes to the 
        ///       control as part of the control viewstate.
        ///  
        protected override void TrackViewState() { 
            base.TrackViewState();
 
            if (titleStyle != null)
                ((IStateManager)titleStyle).TrackViewState();
            if (nextPrevStyle != null)
                ((IStateManager)nextPrevStyle).TrackViewState(); 
            if (dayStyle != null)
                ((IStateManager)dayStyle).TrackViewState(); 
            if (dayHeaderStyle != null) 
                ((IStateManager)dayHeaderStyle).TrackViewState();
            if (todayDayStyle != null) 
                ((IStateManager)todayDayStyle).TrackViewState();
            if (weekendDayStyle != null)
                ((IStateManager)weekendDayStyle).TrackViewState();
            if (otherMonthDayStyle != null) 
                ((IStateManager)otherMonthDayStyle).TrackViewState();
            if (selectedDayStyle != null) 
                ((IStateManager)selectedDayStyle).TrackViewState(); 
            if (selectorStyle != null)
                ((IStateManager)selectorStyle).TrackViewState(); 
        }


        ///  
        /// 
        private int NumericFirstDayOfWeek() { 
            // Used globalized value by default 
            return(FirstDayOfWeek == FirstDayOfWeek.Default)
            ? (int) DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek 
            : (int) FirstDayOfWeek;
        }

 
        /// 
        /// Raises the event for a . 
        ///  
        protected virtual void OnDayRender(TableCell cell, CalendarDay day) {
            DayRenderEventHandler handler = (DayRenderEventHandler)Events[EventDayRender]; 
            if (handler != null) {
                int absoluteDay = day.Date.Subtract(baseDate).Days;

                // VSWhidbey 215383: We return null for selectUrl if a control is not in 
                // the page control tree.
                string selectUrl = null; 
                Page page = Page; 
                if (page != null) {
                    string eventArgument = absoluteDay.ToString(CultureInfo.InvariantCulture); 
                    selectUrl = Page.ClientScript.GetPostBackClientHyperlink(this, eventArgument, true);
                }
                handler(this, new DayRenderEventArgs(cell, day, selectUrl));
            } 
        }
 
#if SHIPPINGADAPTERS 
        // A wrapper to raise the SelectionChangedEvent when a date is selected
        // by the user.  This can be called by adapters when they have 
        // collected the selected date.
        internal void RaiseSelectionChangedEvent() {
            OnSelectionChanged();
        } 
#endif
 
 
        /// 
        /// Raises the event for a . 
        /// 
        protected virtual void OnSelectionChanged() {
            EventHandler handler = (EventHandler)Events[EventSelectionChanged];
            if (handler != null) { 
                handler(this, EventArgs.Empty);
            } 
        } 

 
        /// 
        /// Raises the event for a .
        /// 
        protected virtual void OnVisibleMonthChanged(DateTime newDate, DateTime previousDate) { 
            MonthChangedEventHandler handler = (MonthChangedEventHandler)Events[EventVisibleMonthChanged];
            if (handler != null) { 
                handler(this, new MonthChangedEventArgs(newDate, previousDate)); 
            }
        } 


        /// 
        ///  
        /// Raises events on post back for the  control.
        ///  
        protected virtual void RaisePostBackEvent(string eventArgument) { 

            ValidateEvent(UniqueID, eventArgument); 

            if(_adapter != null) {
                IPostBackEventHandler pbeh = _adapter as IPostBackEventHandler;
                if (pbeh != null) { 
                    pbeh.RaisePostBackEvent(eventArgument);
                } 
            } else { 

                if (String.Compare(eventArgument, 0, NAVIGATE_MONTH_COMMAND, 0, NAVIGATE_MONTH_COMMAND.Length, StringComparison.Ordinal) == 0) { 
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the
                    // base date.
                    DateTime oldDate = VisibleDate;
                    if (oldDate.Equals(DateTime.MinValue)) { 
                        oldDate = TodaysDate;
                    } 
                    int newDateDiff = Int32.Parse(eventArgument.Substring(NAVIGATE_MONTH_COMMAND.Length), CultureInfo.InvariantCulture); 
                    VisibleDate = baseDate.AddDays(newDateDiff);
                    if (VisibleDate == DateTime.MinValue) { 
                        // MinValue would make the calendar shows today's month instead because it
                        // is the default value of VisibleDate property, so we add a day to keep
                        // showing the first supported month.
                        // We assume the first supported month has more than one day. 
                        VisibleDate = DateTimeFormatInfo.CurrentInfo.Calendar.AddDays(VisibleDate, 1);
                    } 
                    OnVisibleMonthChanged(VisibleDate, oldDate); 
                }
                else if (String.Compare(eventArgument, 0, SELECT_RANGE_COMMAND, 0, SELECT_RANGE_COMMAND.Length, StringComparison.Ordinal) == 0) { 
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the
                    // number of days to select.
                    int rangeValue = Int32.Parse(eventArgument.Substring(SELECT_RANGE_COMMAND.Length), CultureInfo.InvariantCulture); 
                    int dayDiff = rangeValue / 100;
                    int dayRange = rangeValue % 100; 
                    if (dayRange < 1) { 
                        dayRange = 100 + dayRange;
                        dayDiff -= 1; 
                    }
                    DateTime dt = baseDate.AddDays(dayDiff);
                    SelectRange(dt, dt.AddDays(dayRange - 1));
                } 
                else {
                    // Single day selection. This is just a number which is the day difference from the base date. 
                    int dayDiff = Int32.Parse(eventArgument, CultureInfo.InvariantCulture); 
                    DateTime dt = baseDate.AddDays(dayDiff);
                    SelectRange(dt, dt); 
                }
            }
        }
 

        void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) { 
            RaisePostBackEvent(eventArgument); 
        }
 

        /// 
        protected internal override void OnPreRender(EventArgs e) {
            base.OnPreRender(e); 
            if (Page != null) {
                Page.RegisterPostBackScript(); 
            } 
        }
 

        /// 
        /// 
        /// Displays the  control on the client. 
        /// 
        protected internal override void Render(HtmlTextWriter writer) { 
            threadCalendar = DateTimeFormatInfo.CurrentInfo.Calendar; 
            minSupportedDate = threadCalendar.MinSupportedDateTime;
            maxSupportedDate = threadCalendar.MaxSupportedDateTime; 
#if DEBUG
            threadCalendarInitialized = true;
#endif
            DateTime visibleDate = EffectiveVisibleDate(); 
            DateTime firstDay = FirstCalendarDay(visibleDate);
            CalendarSelectionMode selectionMode = SelectionMode; 
 
            // Make sure we are in a form tag with runat=server.
            if (Page != null) { 
                Page.VerifyRenderingInServerForm(this);
            }

            // We only want to display the link if we have a page, or if we are on the design surface 
            // If we can stops links being active on the Autoformat dialog, then we can remove this these checks.
            Page page = Page; 
            bool buttonsActive; 
            if (page == null || DesignMode) {
                buttonsActive = false; 
            }
            else {
                buttonsActive = IsEnabled;
            } 

            defaultForeColor = ForeColor; 
            if (defaultForeColor == Color.Empty) { 
                defaultForeColor = DefaultForeColor;
            } 
            defaultButtonColorText = ColorTranslator.ToHtml(defaultForeColor);

            Table table = new Table();
 
            if (ID != null) {
                table.ID = ClientID; 
            } 
            table.CopyBaseAttributes(this);
            if (ControlStyleCreated) { 
                table.ApplyStyle(ControlStyle);
            }
            table.Width = Width;
            table.Height = Height; 
            table.CellPadding = CellPadding;
            table.CellSpacing = CellSpacing; 
 
            // default look
            if ((ControlStyleCreated == false) || 
                (ControlStyle.IsSet(System.Web.UI.WebControls.Style.PROP_BORDERWIDTH) == false) ||
                BorderWidth.Equals(Unit.Empty)) {
                table.BorderWidth = Unit.Pixel(1);
            } 

            if (ShowGridLines) { 
                table.GridLines = GridLines.Both; 
            }
            else { 
                table.GridLines = GridLines.None;
            }

            bool useAccessibleHeader = UseAccessibleHeader; 
            if (useAccessibleHeader) {
                if (table.Attributes["title"] == null) { 
                    table.Attributes["title"] = SR.GetString(SR.Calendar_TitleText); 
                }
            } 

            string caption = Caption;
            if (caption.Length > 0) {
                table.Caption = caption; 
                table.CaptionAlign = CaptionAlign;
            } 
 
            table.RenderBeginTag(writer);
 
            if (ShowTitle) {
                RenderTitle(writer, visibleDate, selectionMode, buttonsActive, useAccessibleHeader);
            }
 
            if (ShowDayHeader) {
                RenderDayHeader(writer, visibleDate, selectionMode, buttonsActive, useAccessibleHeader); 
            } 

            RenderDays(writer, firstDay, visibleDate, selectionMode, buttonsActive, useAccessibleHeader); 

            table.RenderEndTag(writer);
        }
 
        private void RenderCalendarCell(HtmlTextWriter writer, TableItemStyle style, string text, string title, bool hasButton, string eventArgument) {
            style.AddAttributesToRender(writer, this); 
            writer.RenderBeginTag(HtmlTextWriterTag.Td); 

            if (hasButton) { 

                // render the button
                Color foreColor = style.ForeColor;
                writer.Write(""); 
                writer.Write(text);
                writer.Write("");
            }
            else { 
                writer.Write(text);
            } 
 
            writer.RenderEndTag();
        } 

        private void RenderCalendarHeaderCell(HtmlTextWriter writer, TableItemStyle style, string text, string abbrText) {
            style.AddAttributesToRender(writer, this);
            writer.AddAttribute("abbr", abbrText); 
            writer.AddAttribute("scope", "col");
            writer.RenderBeginTag(HtmlTextWriterTag.Th); 
            writer.Write(text); 
            writer.RenderEndTag();
        } 


        /// 
        ///  
        private void RenderDayHeader(HtmlTextWriter writer, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) {
 
            writer.Write(ROWBEGINTAG); 

            DateTimeFormatInfo dtf = DateTimeFormatInfo.CurrentInfo; 

            if (HasWeekSelectors(selectionMode)) {
                TableItemStyle monthSelectorStyle = new TableItemStyle();
                monthSelectorStyle.HorizontalAlign = HorizontalAlign.Center; 
                // add the month selector button if required;
                if (selectionMode == CalendarSelectionMode.DayWeekMonth) { 
 
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the 
                    // number of days to select.
                    int startOffset = visibleDate.Subtract(baseDate).Days;
                    int monthLength = threadCalendar.GetDaysInMonth(threadCalendar.GetYear(visibleDate), threadCalendar.GetMonth(visibleDate), threadCalendar.GetEra(visibleDate));
                    if (IsMinSupportedYearMonth(visibleDate)) { 
                        // The first supported month might not start with day 1
                        // (e.g. Sept 8 is the first supported date of JapaneseCalendar) 
                        monthLength = monthLength - threadCalendar.GetDayOfMonth(visibleDate) + 1; 
                    }
                    else if (IsMaxSupportedYearMonth(visibleDate)) { 
                        // The last supported month might not have all days supported in that calendar month
                        // (e.g. April 3 is the last supported date of HijriCalendar)
                        monthLength = threadCalendar.GetDayOfMonth(maxSupportedDate);
                    } 

                    string monthSelectKey = SELECT_RANGE_COMMAND + ((startOffset * 100) + monthLength).ToString(CultureInfo.InvariantCulture); 
                    monthSelectorStyle.CopyFrom(SelectorStyle); 

                    string selectMonthTitle = null; 
                    if (useAccessibleHeader) {
                        selectMonthTitle = SR.GetString(SR.Calendar_SelectMonthTitle);
                    }
                    RenderCalendarCell(writer, monthSelectorStyle, SelectMonthText, selectMonthTitle, buttonsActive, monthSelectKey); 
                }
                else { 
                    // otherwise make it look like the header row 
                    monthSelectorStyle.CopyFrom(DayHeaderStyle);
                    RenderCalendarCell(writer, monthSelectorStyle, string.Empty, null, false, null); 
                }
            }

            TableItemStyle dayNameStyle = new TableItemStyle(); 
            dayNameStyle.HorizontalAlign = HorizontalAlign.Center;
            dayNameStyle.CopyFrom(DayHeaderStyle); 
            DayNameFormat dayNameFormat = DayNameFormat; 

            int numericFirstDay = NumericFirstDayOfWeek(); 
            for (int i = numericFirstDay; i < numericFirstDay + 7; i++) {
                string dayName;
                int dayOfWeek = i % 7;
                switch (dayNameFormat) { 
                    case DayNameFormat.FirstLetter:
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek).Substring(0, 1); 
                        break; 
                    case DayNameFormat.FirstTwoLetters:
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek).Substring(0, 2); 
                        break;
                    case DayNameFormat.Full:
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek);
                        break; 
                    case DayNameFormat.Short:
                        dayName = dtf.GetAbbreviatedDayName((DayOfWeek)dayOfWeek); 
                        break; 
                    case DayNameFormat.Shortest:
                        dayName = dtf.GetShortestDayName((DayOfWeek)dayOfWeek); 
                        break;
                    default:
                        Debug.Assert(false, "Unknown DayNameFormat value!");
                        goto case DayNameFormat.Short; 
                }
 
                if (useAccessibleHeader) { 
                    string fullDayName = dtf.GetDayName((DayOfWeek)dayOfWeek);
                    RenderCalendarHeaderCell(writer, dayNameStyle, dayName, fullDayName); 
                }
                else {
                    RenderCalendarCell(writer, dayNameStyle, dayName, null, false, null);
                } 
            }
            writer.Write(ROWENDTAG); 
        } 

 
        /// 
        /// 
        private void RenderDays(HtmlTextWriter writer, DateTime firstDay, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) {
            // Now add the rows for the actual days 

            DateTime d = firstDay; 
            TableItemStyle weekSelectorStyle = null; 
            Unit defaultWidth;
            bool hasWeekSelectors = HasWeekSelectors(selectionMode); 
            if (hasWeekSelectors) {
                weekSelectorStyle = new TableItemStyle();
                weekSelectorStyle.Width = Unit.Percentage(12);
                weekSelectorStyle.HorizontalAlign = HorizontalAlign.Center; 
                weekSelectorStyle.CopyFrom(SelectorStyle);
                defaultWidth = Unit.Percentage(12); 
            } 
            else {
                defaultWidth = Unit.Percentage(14); 
            }

            // This determines whether we need to call DateTime.ToString for each day. The only culture/calendar
            // that requires this for now is the HebrewCalendar. 
            bool usesStandardDayDigits = !(threadCalendar is HebrewCalendar);
 
            // This determines whether we can write out cells directly, or whether we have to create whole 
            // TableCell objects for each day.
            bool hasRenderEvent = (this.GetType() != typeof(Calendar) 
                                   || Events[EventDayRender] != null);

            TableItemStyle [] cellStyles = new TableItemStyle[16];
            int definedStyleMask = GetDefinedStyleMask(); 
            DateTime todaysDate = TodaysDate;
            string selectWeekText = SelectWeekText; 
            bool daysSelectable = buttonsActive && (selectionMode != CalendarSelectionMode.None); 
            int visibleDateMonth = threadCalendar.GetMonth(visibleDate);
            int absoluteDay = firstDay.Subtract(baseDate).Days; 

            // VSWhidbey 480155: flag to indicate if forecolor needs to be set
            // explicitly in design mode to mimic runtime rendering with the
            // limitation of not supporting CSS class color setting. 
            bool inDesignSelectionMode = (DesignMode && SelectionMode != CalendarSelectionMode.None);
 
            //----------------------------------------------------------------- 
            // VSWhidbey 366243: The following variables are for boundary cases
            // such as the current visible month is the first or the last 
            // supported month.  They are used in the 'for' loops below.

            // For the first supported month, calculate how many days to
            // skip at the beginning of the first month.  E.g. JapaneseCalendar 
            // starts at Sept 8.
            int numOfFirstDaysToSkip = 0; 
            if (IsMinSupportedYearMonth(visibleDate)) { 
                numOfFirstDaysToSkip = (int)threadCalendar.GetDayOfWeek(firstDay) - NumericFirstDayOfWeek();
                // If negative, it simply means the the index of the starting 
                // day name is greater than the day name of the first supported
                // date.  We add back 7 to get the number of days to skip.
                if (numOfFirstDaysToSkip < 0) {
                    numOfFirstDaysToSkip += 7; 
                }
            } 
            Debug.Assert(numOfFirstDaysToSkip < 7); 

            // For the last or second last supported month, initialize variables 
            // to identify the last supported date of the current calendar.
            // e.g. The last supported date of HijriCalendar is April 3.  When
            // the second last monthh is shown, it can be the case that not all
            // cells will be filled up. 
            bool passedLastSupportedDate = false;
            DateTime secondLastMonth = threadCalendar.AddMonths(maxSupportedDate, -1); 
            bool lastOrSecondLastMonth = (IsMaxSupportedYearMonth(visibleDate) || 
                                IsTheSameYearMonth(secondLastMonth, visibleDate));
            //----------------------------------------------------------------- 

            for (int iRow = 0; iRow < 6; iRow++) {
                if (passedLastSupportedDate) {
                    break; 
                }
 
                writer.Write(ROWBEGINTAG); 

                // add week selector column and button if required 
                if (hasWeekSelectors) {
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the
                    // number of days to select. 
                    int dayDiffParameter = (absoluteDay * 100) + 7;
 
                    // Adjust the dayDiff for the first or the last supported month 
                    if (numOfFirstDaysToSkip > 0) {
                        dayDiffParameter -= numOfFirstDaysToSkip; 
                    }
                    else if (lastOrSecondLastMonth) {
                        int daysFromLastDate = maxSupportedDate.Subtract(d).Days;
                        if (daysFromLastDate < 6) { 
                            dayDiffParameter -= (6 - daysFromLastDate);
                        } 
                    } 
                    string weekSelectKey = SELECT_RANGE_COMMAND + dayDiffParameter.ToString(CultureInfo.InvariantCulture);
 
                    string selectWeekTitle = null;
                    if (useAccessibleHeader) {
                        int weekOfMonth = iRow + 1;
                        selectWeekTitle = SR.GetString(SR.Calendar_SelectWeekTitle, weekOfMonth.ToString(CultureInfo.InvariantCulture)); 
                    }
                    RenderCalendarCell(writer, weekSelectorStyle, selectWeekText, selectWeekTitle, buttonsActive, weekSelectKey); 
                } 

                for (int iDay = 0; iDay < 7; iDay++) { 

                    // Render empty cells for special cases to handle the first
                    // or last supported month.
                    if (numOfFirstDaysToSkip > 0) { 
                        iDay += numOfFirstDaysToSkip;
                        for ( ; numOfFirstDaysToSkip > 0; numOfFirstDaysToSkip--) { 
                            writer.RenderBeginTag(HtmlTextWriterTag.Td); 
                            writer.RenderEndTag();
                        } 
                    }
                    else if (passedLastSupportedDate) {
                        for ( ; iDay < 7; iDay++) {
                            writer.RenderBeginTag(HtmlTextWriterTag.Td); 
                            writer.RenderEndTag();
                        } 
                        break; 
                    }
 
                    int dayOfWeek = (int)threadCalendar.GetDayOfWeek(d);
                    int dayOfMonth = threadCalendar.GetDayOfMonth(d);
                    string dayNumberText;
                    if ((dayOfMonth <= cachedNumberMax) && usesStandardDayDigits) { 
                        dayNumberText = cachedNumbers[dayOfMonth];
                    } 
                    else { 
                        dayNumberText = d.ToString("dd", CultureInfo.CurrentCulture);
                    } 

                    CalendarDay day = new CalendarDay(d,
                                                      (dayOfWeek == 0 || dayOfWeek == 6), // IsWeekend
                                                      d.Equals(todaysDate), // IsToday 
                                                      (selectedDates != null) && selectedDates.Contains(d), // IsSelected
                                                      threadCalendar.GetMonth(d) != visibleDateMonth, // IsOtherMonth 
                                                      dayNumberText // Number Text 
                                                      );
 
                    int styleMask = STYLEMASK_DAY;
                    if (day.IsSelected)
                        styleMask |= STYLEMASK_SELECTED;
                    if (day.IsOtherMonth) 
                        styleMask |= STYLEMASK_OTHERMONTH;
                    if (day.IsToday) 
                        styleMask |= STYLEMASK_TODAY; 
                    if (day.IsWeekend)
                        styleMask |= STYLEMASK_WEEKEND; 
                    int dayStyleMask = definedStyleMask  & styleMask;
                    // determine the unique portion of the mask for the current calendar,
                    // which will strip out the day style bit
                    int dayStyleID = dayStyleMask & STYLEMASK_UNIQUE; 

                    TableItemStyle cellStyle = cellStyles[dayStyleID]; 
                    if (cellStyle == null) { 
                        cellStyle = new TableItemStyle();
                        SetDayStyles(cellStyle, dayStyleMask, defaultWidth); 
                        cellStyles[dayStyleID] = cellStyle;
                    }

 
                    string dayTitle = null;
                    if (useAccessibleHeader) { 
                        dayTitle = d.ToString("m", CultureInfo.CurrentCulture); 
                    }
 
                    if (hasRenderEvent) {

                        TableCell cdc = new TableCell();
                        cdc.ApplyStyle(cellStyle); 

                        LiteralControl dayContent = new LiteralControl(dayNumberText); 
                        cdc.Controls.Add(dayContent); 

                        day.IsSelectable = daysSelectable; 

                        OnDayRender(cdc, day);

                        // refresh the day content 
                        dayContent.Text = GetCalendarButtonText(absoluteDay.ToString(CultureInfo.InvariantCulture),
                                                                dayNumberText, 
                                                                dayTitle, 
                                                                buttonsActive && day.IsSelectable,
                                                                cdc.ForeColor); 
                        cdc.RenderControl(writer);

                    }
                    else { 
                        // VSWhidbey 480155: In design mode we render days as
                        // texts instead of links so CSS class color setting is 
                        // supported.  But this differs in runtime rendering 
                        // where CSS class color setting is not supported.  To
                        // correctly mimic the forecolor of runtime rendering in 
                        // design time, the default color, which is used in
                        // runtime rendering, is explicitly set in this case.
                        if (inDesignSelectionMode && cellStyle.ForeColor.IsEmpty) {
                            cellStyle.ForeColor = defaultForeColor; 
                        }
 
                        RenderCalendarCell(writer, cellStyle, dayNumberText, dayTitle, daysSelectable, absoluteDay.ToString(CultureInfo.InvariantCulture)); 
                    }
 
                    Debug.Assert(!passedLastSupportedDate);
                    if (lastOrSecondLastMonth && d.Month == maxSupportedDate.Month && d.Day == maxSupportedDate.Day) {
                        passedLastSupportedDate = true;
                    } 
                    else {
                        d = threadCalendar.AddDays(d, 1); 
                        absoluteDay++; 
                    }
                } 
                writer.Write(ROWENDTAG);
            }
        }
 

        ///  
        ///  
        private void RenderTitle(HtmlTextWriter writer, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) {
            writer.Write(ROWBEGINTAG); 

            TableCell titleCell = new TableCell();
            Table titleTable = new Table();
 
            // default title table/cell styles
            titleCell.ColumnSpan = HasWeekSelectors(selectionMode) ? 8 : 7; 
            titleCell.BackColor = Color.Silver; 
            titleTable.GridLines = GridLines.None;
            titleTable.Width = Unit.Percentage(100); 
            titleTable.CellSpacing = 0;

            TableItemStyle titleStyle = TitleStyle;
            ApplyTitleStyle(titleCell, titleTable, titleStyle); 

            titleCell.RenderBeginTag(writer); 
            titleTable.RenderBeginTag(writer); 
            writer.Write(ROWBEGINTAG);
 
            NextPrevFormat nextPrevFormat = NextPrevFormat;

            TableItemStyle nextPrevStyle = new TableItemStyle();
            nextPrevStyle.Width = Unit.Percentage(15); 
            nextPrevStyle.CopyFrom(NextPrevStyle);
            if (ShowNextPrevMonth) { 
                if (IsMinSupportedYearMonth(visibleDate)) { 
                    writer.RenderBeginTag(HtmlTextWriterTag.Td);
                    writer.RenderEndTag(); 
                }
                else {
                    string prevMonthText;
                    if (nextPrevFormat == NextPrevFormat.ShortMonth || nextPrevFormat == NextPrevFormat.FullMonth) { 
                        int monthNo = threadCalendar.GetMonth(threadCalendar.AddMonths(visibleDate, - 1));
                        prevMonthText = GetMonthName(monthNo, (nextPrevFormat == NextPrevFormat.FullMonth)); 
                    } 
                    else {
                        prevMonthText = PrevMonthText; 
                    }
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the
                    // base date.
                    DateTime prevMonthDate; 

                    // VSWhidbey 366243: Some calendar's min supported date is 
                    // not the first day of the month (e.g. JapaneseCalendar. 
                    // So if we are setting the second supported month, the prev
                    // month link should always point to the first supported 
                    // date instead of the first day of the previous month.
                    DateTime secondSupportedMonth = threadCalendar.AddMonths(minSupportedDate, 1);
                    if (IsTheSameYearMonth(secondSupportedMonth, visibleDate)) {
                        prevMonthDate = minSupportedDate; 
                    }
                    else { 
                        prevMonthDate = threadCalendar.AddMonths(visibleDate, -1); 
                    }
 
                    string prevMonthKey = NAVIGATE_MONTH_COMMAND + (prevMonthDate.Subtract(baseDate)).Days.ToString(CultureInfo.InvariantCulture);

                    string previousMonthTitle = null;
                    if (useAccessibleHeader) { 
                        previousMonthTitle = SR.GetString(SR.Calendar_PreviousMonthTitle);
                    } 
                    RenderCalendarCell(writer, nextPrevStyle, prevMonthText, previousMonthTitle, buttonsActive, prevMonthKey); 
                }
            } 


            TableItemStyle cellMainStyle = new TableItemStyle();
 
            if (titleStyle.HorizontalAlign != HorizontalAlign.NotSet) {
                cellMainStyle.HorizontalAlign = titleStyle.HorizontalAlign; 
            } 
            else {
                cellMainStyle.HorizontalAlign = HorizontalAlign.Center; 
            }
            cellMainStyle.Wrap = titleStyle.Wrap;
            cellMainStyle.Width = Unit.Percentage(70);
 
            string titleText;
 
            switch (TitleFormat) { 
                case TitleFormat.Month:
                    titleText = visibleDate.ToString("MMMM", CultureInfo.CurrentCulture); 
                    break;
                case TitleFormat.MonthYear:
                    string titlePattern = DateTimeFormatInfo.CurrentInfo.YearMonthPattern;
                    // Some cultures have a comma in their YearMonthPattern, which does not look 
                    // right in a calendar. Use a fixed pattern for those.
                    if (titlePattern.IndexOf(',') >= 0) { 
                        titlePattern = "MMMM yyyy"; 
                    }
                    titleText = visibleDate.ToString(titlePattern, CultureInfo.CurrentCulture); 
                    break;
                default:
                    Debug.Assert(false, "Unknown TitleFormat value!");
                    goto case TitleFormat.MonthYear; 
            }
            RenderCalendarCell(writer, cellMainStyle, titleText, null, false, null); 
 
            if (ShowNextPrevMonth) {
                if (IsMaxSupportedYearMonth(visibleDate)) { 
                    writer.RenderBeginTag(HtmlTextWriterTag.Td);
                    writer.RenderEndTag();
                }
                else { 
                    // Style for this one is identical bar
                    nextPrevStyle.HorizontalAlign = HorizontalAlign.Right; 
                    string nextMonthText; 
                    if (nextPrevFormat == NextPrevFormat.ShortMonth || nextPrevFormat == NextPrevFormat.FullMonth) {
                        int monthNo = threadCalendar.GetMonth(threadCalendar.AddMonths(visibleDate, 1)); 
                        nextMonthText = GetMonthName(monthNo, (nextPrevFormat == NextPrevFormat.FullMonth));
                    }
                    else {
                        nextMonthText = NextMonthText; 
                    }
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the 
                    // base date. 
                    DateTime nextMonthDate = threadCalendar.AddMonths(visibleDate, 1);
                    string nextMonthKey = NAVIGATE_MONTH_COMMAND + (nextMonthDate.Subtract(baseDate)).Days.ToString(CultureInfo.InvariantCulture); 

                    string nextMonthTitle = null;
                    if (useAccessibleHeader) {
                        nextMonthTitle = SR.GetString(SR.Calendar_NextMonthTitle); 
                    }
                    RenderCalendarCell(writer, nextPrevStyle, nextMonthText, nextMonthTitle, buttonsActive, nextMonthKey); 
                } 
            }
            writer.Write(ROWENDTAG); 
            titleTable.RenderEndTag(writer);
            titleCell.RenderEndTag(writer);
            writer.Write(ROWENDTAG);
 
        }
 
 
        /// 
        ///  
        /// Stores the state of the System.Web.UI.WebControls.Calender.
        /// 
        protected override object SaveViewState() {
            if (SelectedDates.Count > 0) 
                ViewState["SD"] = dateList;
 
            object[] myState = new object[10]; 

            myState[0] = base.SaveViewState(); 
            myState[1] = (titleStyle != null) ? ((IStateManager)titleStyle).SaveViewState() : null;
            myState[2] = (nextPrevStyle != null) ? ((IStateManager)nextPrevStyle).SaveViewState() : null;
            myState[3] = (dayStyle != null) ? ((IStateManager)dayStyle).SaveViewState() : null;
            myState[4] = (dayHeaderStyle != null) ? ((IStateManager)dayHeaderStyle).SaveViewState() : null; 
            myState[5] = (todayDayStyle != null) ? ((IStateManager)todayDayStyle).SaveViewState() : null;
            myState[6] = (weekendDayStyle != null) ? ((IStateManager)weekendDayStyle).SaveViewState() : null; 
            myState[7] = (otherMonthDayStyle != null) ? ((IStateManager)otherMonthDayStyle).SaveViewState() : null; 
            myState[8] = (selectedDayStyle != null) ? ((IStateManager)selectedDayStyle).SaveViewState() : null;
            myState[9] = (selectorStyle != null) ? ((IStateManager)selectorStyle).SaveViewState() : null; 

            for (int i = 0; i
        ///  
        private void SetDayStyles(TableItemStyle style, int styleMask, Unit defaultWidth) {

            // default day styles
            style.Width = defaultWidth; 
            style.HorizontalAlign = HorizontalAlign.Center;
 
            if ((styleMask & STYLEMASK_DAY) != 0) { 
                style.CopyFrom(DayStyle);
            } 
            if ((styleMask & STYLEMASK_WEEKEND) != 0) {
                style.CopyFrom(WeekendDayStyle);
            }
            if ((styleMask & STYLEMASK_OTHERMONTH) != 0) { 
                style.CopyFrom(OtherMonthDayStyle);
            } 
            if ((styleMask & STYLEMASK_TODAY) != 0) { 
                style.CopyFrom(TodayDayStyle);
            } 

            if ((styleMask & STYLEMASK_SELECTED) != 0) {
                // default selected day style
                style.ForeColor = Color.White; 
                style.BackColor = Color.Silver;
 
                style.CopyFrom(SelectedDayStyle); 
            }
        } 
    }
}

 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls { 
    using System.Threading; 
    using System.Globalization;
    using System.ComponentModel; 
    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.Util; 
    using System.Collections;
    using System.ComponentModel.Design; 
    using System.Drawing; 
    using System.Text;
 
    using System.IO;
    using System.Reflection;
    using System.Security.Permissions;
 

 
    ///  
    ///    Displays a one-month calendar and allows the user to
    ///       view and select a specific day, week, or month. 
    /// 
    [
    ControlValueProperty("SelectedDate", typeof(DateTime), "1/1/0001"),
    DataBindingHandler("System.Web.UI.Design.WebControls.CalendarDataBindingHandler, " + AssemblyRef.SystemDesign), 
    DefaultEvent("SelectionChanged"),
    DefaultProperty("SelectedDate"), 
    Designer("System.Web.UI.Design.WebControls.CalendarDesigner, " + AssemblyRef.SystemDesign), 
    SupportsEventValidation
    ] 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    public class Calendar : WebControl, IPostBackEventHandler {
 
        private static readonly object EventDayRender = new object();
        private static readonly object EventSelectionChanged = new object(); 
        private static readonly object EventVisibleMonthChanged = new object(); 

        private TableItemStyle titleStyle; 
        private TableItemStyle nextPrevStyle;
        private TableItemStyle dayHeaderStyle;
        private TableItemStyle selectorStyle;
        private TableItemStyle dayStyle; 
        private TableItemStyle otherMonthDayStyle;
        private TableItemStyle todayDayStyle; 
        private TableItemStyle selectedDayStyle; 
        private TableItemStyle weekendDayStyle;
        private string defaultButtonColorText; 

        private static readonly Color DefaultForeColor = Color.Black;
        private Color defaultForeColor;
 
        private ArrayList dateList;
        private SelectedDatesCollection selectedDates; 
        private Globalization.Calendar threadCalendar; 
        private DateTime minSupportedDate;
        private DateTime maxSupportedDate; 
#if DEBUG
        private bool threadCalendarInitialized;
#endif
 
        private const string SELECT_RANGE_COMMAND = "R";
        private const string NAVIGATE_MONTH_COMMAND = "V"; 
 
        private static DateTime baseDate = new DateTime(2000, 1, 1);
 
        private const int STYLEMASK_DAY = 16;
        private const int STYLEMASK_UNIQUE = 15;
        private const int STYLEMASK_SELECTED = 8;
        private const int STYLEMASK_TODAY = 4; 
        private const int STYLEMASK_OTHERMONTH = 2;
        private const int STYLEMASK_WEEKEND = 1; 
        private const string ROWBEGINTAG = ""; 
        private const string ROWENDTAG = "";
 
        // Cache commonly used strings. This improves performance and memory usage.
        private const int cachedNumberMax = 31;
        private static readonly string[] cachedNumbers = new string [] {
                  "0",  "1",   "2",   "3",   "4",   "5",   "6", 
                  "7",  "8",   "9",  "10",  "11",  "12",  "13",
                 "14", "15",  "16",  "17",  "18",  "19",  "20", 
                 "21", "22",  "23",  "24",  "25",  "26",  "27", 
                 "28", "29",  "30",  "31",
        }; 


        /// 
        /// Initializes a new instance of the  class. 
        /// 
        public Calendar() : base(HtmlTextWriterTag.Table) { 
        } 

 
        [
        Localizable(true),
        DefaultValue(""),
        WebCategory("Accessibility"), 
        WebSysDescription(SR.Calendar_Caption)
        ] 
        public virtual string Caption { 
            get {
                string s = (string)ViewState["Caption"]; 
                return (s != null) ? s : String.Empty;
            }
            set {
                ViewState["Caption"] = value; 
            }
        } 
 

        [ 
        DefaultValue(TableCaptionAlign.NotSet),
        WebCategory("Accessibility"),
        WebSysDescription(SR.WebControl_CaptionAlign)
        ] 
        public virtual TableCaptionAlign CaptionAlign {
            get { 
                object o = ViewState["CaptionAlign"]; 
                return (o != null) ? (TableCaptionAlign)o : TableCaptionAlign.NotSet;
            } 
            set {
                if ((value < TableCaptionAlign.NotSet) ||
                    (value > TableCaptionAlign.Right)) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["CaptionAlign"] = value; 
            } 
        }
 

        /// 
        ///    Gets or sets the amount of space between cells.
        ///  
        [
        WebCategory("Layout"), 
        DefaultValue(2), 
        WebSysDescription(SR.Calendar_CellPadding)
        ] 
        public int CellPadding {
            get {
                object o = ViewState["CellPadding"];
                return((o == null) ? 2 : (int)o); 
            }
            set { 
                if (value < - 1 ) { 
                    throw new ArgumentOutOfRangeException("value");
                } 
                ViewState["CellPadding"] = value;
            }
        }
 

        ///  
        ///    Gets or sets the amount of space between the contents of a cell 
        ///       and the cell's border.
        ///  
        [
        WebCategory("Layout"),
        DefaultValue(0),
        WebSysDescription(SR.Calendar_CellSpacing) 
        ]
        public int CellSpacing { 
            get { 
                object o = ViewState["CellSpacing"];
                return((o == null) ?  0 : (int)o); 
            }
            set {
                if (value < -1 ) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["CellSpacing"] = (int)value; 
            } 
        }
 

        /// 
        ///     Gets the style property of the day-of-the-week header. This property is read-only.
        ///  
        [
        WebCategory("Styles"), 
        WebSysDescription(SR.Calendar_DayHeaderStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle DayHeaderStyle {
            get { 
                if (dayHeaderStyle == null) {
                    dayHeaderStyle = new TableItemStyle(); 
                    if (IsTrackingViewState) 
                        ((IStateManager)dayHeaderStyle).TrackViewState();
                } 
                return dayHeaderStyle;
            }
        }
 

        ///  
        ///    Gets or sets 
        ///       the format for the names of days.
        ///  
        [
        WebCategory("Appearance"),
        DefaultValue(DayNameFormat.Short),
        WebSysDescription(SR.Calendar_DayNameFormat) 
        ]
        public DayNameFormat DayNameFormat { 
            get { 
                object dnf = ViewState["DayNameFormat"];
                return((dnf == null) ? DayNameFormat.Short : (DayNameFormat)dnf); 
            }
            set {
                if (value < DayNameFormat.Full || value > DayNameFormat.Shortest) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["DayNameFormat"] = value; 
            } 
        }
 

        /// 
        ///     Gets the style properties for the days. This property is read-only.
        ///  
        [
        WebCategory("Styles"), 
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_DayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty)
        ]
        public TableItemStyle DayStyle { 
            get {
                if (dayStyle == null) { 
                    dayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)dayStyle).TrackViewState(); 
                }
                return dayStyle;
            }
        } 

 
        ///  
        ///     Gets
        ///       or sets the day of the week to display in the calendar's first 
        ///       column.
        /// 
        [
        WebCategory("Appearance"), 
        DefaultValue(FirstDayOfWeek.Default),
        WebSysDescription(SR.Calendar_FirstDayOfWeek) 
        ] 
        public FirstDayOfWeek FirstDayOfWeek {
            get { 
                object o = ViewState["FirstDayOfWeek"];
                return((o == null) ? FirstDayOfWeek.Default : (FirstDayOfWeek)o);
            }
            set { 
                if (value < FirstDayOfWeek.Sunday || value > FirstDayOfWeek.Default) {
                    throw new ArgumentOutOfRangeException("value"); 
                } 

                ViewState["FirstDayOfWeek"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets the text shown for the next month 
        ///       navigation hyperlink if the  property is set to 
        ///    .
        ///  
        [
        Localizable(true),
        WebCategory("Appearance"),
        DefaultValue(">"), 
        WebSysDescription(SR.Calendar_NextMonthText)
        ] 
        public string NextMonthText { 
            get {
                object s = ViewState["NextMonthText"]; 
                return((s == null) ? ">" : (String) s);
            }
            set {
                ViewState["NextMonthText"] = value; 
            }
        } 
 

        ///  
        ///    Gets or sets the format of the next and previous month hyperlinks in the
        ///       title.
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(NextPrevFormat.CustomText), 
        WebSysDescription(SR.Calendar_NextPrevFormat) 
        ]
        public NextPrevFormat NextPrevFormat { 
            get {
                object npf = ViewState["NextPrevFormat"];
                return((npf == null) ? NextPrevFormat.CustomText : (NextPrevFormat)npf);
            } 
            set {
                if (value < NextPrevFormat.CustomText || value > NextPrevFormat.FullMonth) { 
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["NextPrevFormat"] = value; 
            }
        }

 
        /// 
        ///     Gets the style properties for the next/previous month navigators. This property is 
        ///       read-only. 
        /// 
        [ 
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_NextPrevStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle NextPrevStyle { 
            get {
                if (nextPrevStyle == null) { 
                    nextPrevStyle = new TableItemStyle();
                    if (IsTrackingViewState)
                        ((IStateManager)nextPrevStyle).TrackViewState();
                } 
                return nextPrevStyle;
            } 
        } 

 

        /// 
        ///    Gets the style properties for the days from the months preceding and following the current month.
        ///       This property is read-only. 
        /// 
        [ 
        WebCategory("Styles"), 
        DefaultValue(null),
        WebSysDescription(SR.Calendar_OtherMonthDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle OtherMonthDayStyle {
            get { 
                if (otherMonthDayStyle == null) { 
                    otherMonthDayStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)otherMonthDayStyle).TrackViewState();

                }
                return otherMonthDayStyle; 
            }
        } 
 

        ///  
        ///    Gets or sets the text shown for the previous month
        ///       navigation hyperlink if the  property is set to
        ///    
        ///    . 
        /// 
        [ 
        Localizable(true), 
        WebCategory("Appearance"),
        DefaultValue("<"), 
        WebSysDescription(SR.Calendar_PrevMonthText)
        ]
        public string PrevMonthText {
            get { 
                object s = ViewState["PrevMonthText"];
                return((s == null) ? "<" : (String) s); 
            } 
            set {
                ViewState["PrevMonthText"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets the date that is currently selected 
        ///       date. 
        /// 
        [ 
        Bindable(true, BindingDirection.TwoWay),
        DefaultValue(typeof(DateTime), "1/1/0001"),
        WebSysDescription(SR.Calendar_SelectedDate)
        ] 
        public DateTime SelectedDate {
            get { 
                if (SelectedDates.Count == 0) { 
                    return DateTime.MinValue;
                } 
                return SelectedDates[0];
            }
            set {
                if (value == DateTime.MinValue) { 
                    SelectedDates.Clear();
                } 
                else { 
                    SelectedDates.SelectRange(value, value);
                } 
            }
        }

 
        /// 
        /// Gets a collection of  objects representing days selected on the . This 
        ///    property is read-only. 
        /// 
        [ 
        Browsable(false),
        WebSysDescription(SR.Calendar_SelectedDates),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public SelectedDatesCollection SelectedDates {
            get { 
                if (selectedDates == null) { 
                    if (dateList == null) {
                        dateList = new ArrayList(); 
                    }
                    selectedDates = new SelectedDatesCollection(dateList);
                }
                return selectedDates; 
            }
        } 
 

        ///  
        ///    Gets the style properties for the selected date. This property is read-only.
        /// 
        [
        WebCategory("Styles"), 
        DefaultValue(null),
        WebSysDescription(SR.Calendar_SelectedDayStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty) 
        ]
        public TableItemStyle SelectedDayStyle {
            get {
                if (selectedDayStyle == null) { 
                    selectedDayStyle = new TableItemStyle();
                    if (IsTrackingViewState) 
                        ((IStateManager)selectedDayStyle).TrackViewState(); 
                }
                return selectedDayStyle; 
            }
        }

 
        /// 
        ///    Gets or sets the date selection capabilities on the 
        ///     
        ///    to allow the user to select a day, week, or month.
        ///  
        [
        WebCategory("Behavior"),
        DefaultValue(CalendarSelectionMode.Day),
        WebSysDescription(SR.Calendar_SelectionMode) 
        ]
        public CalendarSelectionMode SelectionMode { 
            get { 
                object csm = ViewState["SelectionMode"];
                return((csm == null) ? CalendarSelectionMode.Day : (CalendarSelectionMode)csm); 
            }
            set {
                if (value < CalendarSelectionMode.None || value > CalendarSelectionMode.DayWeekMonth) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["SelectionMode"] = value; 
            } 
        }
 

        /// 
        ///    Gets or sets the text shown for the month selection in
        ///       the selector column if  is 
        ///    .
        ///  
        [ 
        Localizable(true),
        WebCategory("Appearance"), 
        DefaultValue(">>"),
        WebSysDescription(SR.Calendar_SelectMonthText)
        ]
        public string SelectMonthText { 
            get {
                object s = ViewState["SelectMonthText"]; 
                return((s == null) ? ">>" : (String) s); 
            }
            set { 
                ViewState["SelectMonthText"] = value;
            }
        }
 

        ///  
        ///     Gets the style properties for the week and month selectors. This property is read-only. 
        /// 
        [ 
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_SelectorStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle SelectorStyle { 
            get {
                if (selectorStyle == null) { 
                    selectorStyle = new TableItemStyle();
                    if (IsTrackingViewState)
                        ((IStateManager)selectorStyle).TrackViewState();
                } 
                return selectorStyle;
            } 
        } 

        ///  
        ///    Gets or sets the text shown for the week selection in
        ///       the selector column if  is
        ///    or
        ///    . 
        /// 
        [ 
        Localizable(true), 
        WebCategory("Appearance"),
        DefaultValue(">"), 
        WebSysDescription(SR.Calendar_SelectWeekText)
        ]
        public string SelectWeekText {
            get { 
                object s = ViewState["SelectWeekText"];
                return((s == null) ? ">" : (String) s); 
            } 
            set {
                ViewState["SelectWeekText"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets 
        ///       a value indicating whether the days of the week are displayed. 
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(true),
        WebSysDescription(SR.Calendar_ShowDayHeader)
        ] 
        public bool ShowDayHeader {
            get { 
                object b = ViewState["ShowDayHeader"]; 
                return((b == null) ? true : (bool)b);
            } 
            set {
                ViewState["ShowDayHeader"] = value;
            }
        } 

 
        ///  
        ///    Gets or set
        ///       a value indicating whether days on the calendar are displayed with a border. 
        /// 
        [
        WebCategory("Appearance"),
        DefaultValue(false), 
        WebSysDescription(SR.Calendar_ShowGridLines)
        ] 
        public bool ShowGridLines { 
            get {
                object b= ViewState["ShowGridLines"]; 
                return((b == null) ? false : (bool)b);
            }
            set {
                ViewState["ShowGridLines"] = value; 
            }
        } 
 

        ///  
        /// Gets or sets a value indicating whether the 
        /// displays the next and pervious month
        /// hyperlinks in the title.
        ///  
        [
        WebCategory("Appearance"), 
        DefaultValue(true), 
        WebSysDescription(SR.Calendar_ShowNextPrevMonth)
        ] 
        public bool ShowNextPrevMonth {
            get {
                object b = ViewState["ShowNextPrevMonth"];
                return((b == null) ? true : (bool)b); 
            }
            set { 
                ViewState["ShowNextPrevMonth"] = value; 
            }
        } 


        /// 
        ///     Gets or 
        ///       sets a value indicating whether the title is displayed.
        ///  
        [ 
        WebCategory("Appearance"),
        DefaultValue(true), 
        WebSysDescription(SR.Calendar_ShowTitle)
        ]
        public bool ShowTitle {
            get { 
                object b = ViewState["ShowTitle"];
                return((b == null) ? true : (bool)b); 
            } 
            set {
                ViewState["ShowTitle"] = value; 
            }
        }

 
        /// 
        ///    Gets or sets how the month name is formatted in the title 
        ///       bar. 
        /// 
        [ 
        WebCategory("Appearance"),
        DefaultValue(TitleFormat.MonthYear),
        WebSysDescription(SR.Calendar_TitleFormat)
        ] 
        public TitleFormat TitleFormat {
            get { 
                object tf = ViewState["TitleFormat"]; 
                return((tf == null) ? TitleFormat.MonthYear : (TitleFormat)tf);
            } 
            set {
                if (value < TitleFormat.Month || value > TitleFormat.MonthYear) {
                    throw new ArgumentOutOfRangeException("value");
                } 
                ViewState["TitleFormat"] = value;
            } 
        } 

 
        /// 
        /// Gets the style properties of the  title. This property is
        ///    read-only.
        ///  
        [
        WebCategory("Styles"), 
        WebSysDescription(SR.Calendar_TitleStyle), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty),
        ]
        public TableItemStyle TitleStyle {
            get { 
                if (titleStyle == null) {
                    titleStyle = new TableItemStyle(); 
                    if (IsTrackingViewState) 
                        ((IStateManager)titleStyle).TrackViewState();
                } 
                return titleStyle;
            }
        }
 

        ///  
        ///    Gets the style properties for today's date on the 
        ///    . This
        ///       property is read-only. 
        /// 
        [
        WebCategory("Styles"),
        DefaultValue(null), 
        WebSysDescription(SR.Calendar_TodayDayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle TodayDayStyle {
            get {
                if (todayDayStyle == null) {
                    todayDayStyle = new TableItemStyle(); 
                    if (IsTrackingViewState)
                        ((IStateManager)todayDayStyle).TrackViewState(); 
                } 
                return todayDayStyle;
            } 
        }


        ///  
        ///    Gets or sets the value to use as today's date.
        ///  
        [ 
        Browsable(false),
        WebSysDescription(SR.Calendar_TodaysDate), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public DateTime TodaysDate {
            get { 
                object o = ViewState["TodaysDate"];
                return((o == null) ? DateTime.Today : (DateTime)o); 
            } 
            set {
                ViewState["TodaysDate"] = value.Date; 
            }
        }

 
        [
        DefaultValue(true), 
        WebCategory("Accessibility"), 
        WebSysDescription(SR.Table_UseAccessibleHeader)
        ] 
        public virtual bool UseAccessibleHeader {
            get {
                object o = ViewState["UseAccessibleHeader"];
                return (o != null) ? (bool)o : true; 
            }
            set { 
                ViewState["UseAccessibleHeader"] = value; 
            }
        } 


        /// 
        ///    Gets or sets the date that specifies what month to display. The date can be 
        ///       be any date within the month.
        ///  
        [ 
        Bindable(true),
        DefaultValue(typeof(DateTime), "1/1/0001"), 
        WebSysDescription(SR.Calendar_VisibleDate)
        ]
        public DateTime VisibleDate {
            get { 
                object o = ViewState["VisibleDate"];
                return((o == null) ? DateTime.MinValue : (DateTime)o); 
            } 
            set {
                ViewState["VisibleDate"] = value.Date; 
            }
        }

 
        /// 
        ///    Gets the style properties for the displaying weekend dates. This property is 
        ///       read-only. 
        /// 
        [ 
        WebCategory("Styles"),
        WebSysDescription(SR.Calendar_WeekendDayStyle),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty)
        ] 
        public TableItemStyle WeekendDayStyle { 
            get {
                if (weekendDayStyle == null) { 
                    weekendDayStyle = new TableItemStyle();
                    if (IsTrackingViewState)
                        ((IStateManager)weekendDayStyle).TrackViewState();
                } 
                return weekendDayStyle;
            } 
        } 

 

        /// 
        /// Occurs when each day is created in teh control hierarchy for the .
        ///  
        [
        WebCategory("Action"), 
        WebSysDescription(SR.Calendar_OnDayRender) 
        ]
        public event DayRenderEventHandler DayRender { 
            add {
                Events.AddHandler(EventDayRender, value);
            }
            remove { 
                Events.RemoveHandler(EventDayRender, value);
            } 
        } 

 


        /// 
        ///    Occurs when the user clicks on a day, week, or month 
        ///       selector and changes the .
        ///  
        [ 
        WebCategory("Action"),
        WebSysDescription(SR.Calendar_OnSelectionChanged) 
        ]
        public event EventHandler SelectionChanged {
            add {
                Events.AddHandler(EventSelectionChanged, value); 
            }
            remove { 
                Events.RemoveHandler(EventSelectionChanged, value); 
            }
        } 



        ///  
        ///    Occurs when the
        ///       user clicks on the next or previous month  controls on the title. 
        ///  
        [
        WebCategory("Action"), 
        WebSysDescription(SR.Calendar_OnVisibleMonthChanged)
        ]
        public event MonthChangedEventHandler VisibleMonthChanged {
            add { 
                Events.AddHandler(EventVisibleMonthChanged, value);
            } 
            remove { 
                Events.RemoveHandler(EventVisibleMonthChanged, value);
            } 
        }

        // Methods
 

        ///  
        ///  
        private void ApplyTitleStyle(TableCell titleCell, Table titleTable, TableItemStyle titleStyle) {
            // apply affects that affect the whole background to the cell 
            if (titleStyle.BackColor != Color.Empty) {
                titleCell.BackColor = titleStyle.BackColor;
            }
            if (titleStyle.BorderColor != Color.Empty) { 
                titleCell.BorderColor = titleStyle.BorderColor;
            } 
            if (titleStyle.BorderWidth != Unit.Empty) { 
                titleCell.BorderWidth= titleStyle.BorderWidth;
            } 
            if (titleStyle.BorderStyle != BorderStyle.NotSet) {
                titleCell.BorderStyle = titleStyle.BorderStyle;
            }
            if (titleStyle.Height != Unit.Empty) { 
                titleCell.Height = titleStyle.Height;
            } 
            if (titleStyle.VerticalAlign != VerticalAlign.NotSet) { 
                titleCell.VerticalAlign = titleStyle.VerticalAlign;
            } 

            // apply affects that affect everything else to the table
            if (titleStyle.CssClass.Length > 0) {
                titleTable.CssClass = titleStyle.CssClass; 
            }
            else if (CssClass.Length > 0) { 
                titleTable.CssClass = CssClass; 
            }
 
            if (titleStyle.ForeColor != Color.Empty) {
                titleTable.ForeColor = titleStyle.ForeColor;
            }
            else if (ForeColor != Color.Empty) { 
                titleTable.ForeColor = ForeColor;
            } 
            titleTable.Font.CopyFrom(titleStyle.Font); 
            titleTable.Font.MergeWith(this.Font);
 
        }


        ///  
        /// 
        ///  
        protected override ControlCollection CreateControlCollection() { 
            return new InternalControlCollection(this);
        } 



        ///  
        /// 
        private DateTime EffectiveVisibleDate() { 
            DateTime visDate = VisibleDate; 
            if (visDate.Equals(DateTime.MinValue)) {
                visDate = TodaysDate; 
            }

            // VSWhidbey 366243
            if (IsMinSupportedYearMonth(visDate)) { 
                return minSupportedDate;
            } 
            else { 
                return threadCalendar.AddDays(visDate, -(threadCalendar.GetDayOfMonth(visDate) - 1));
            } 
        }


        ///  
        /// 
        private DateTime FirstCalendarDay(DateTime visibleDate) { 
            DateTime firstDayOfMonth = visibleDate; 

            // VSWhidbey 366243 
            if (IsMinSupportedYearMonth(firstDayOfMonth)) {
                return firstDayOfMonth;
            }
 
            int daysFromLastMonth = ((int)threadCalendar.GetDayOfWeek(firstDayOfMonth)) - NumericFirstDayOfWeek();
            // Always display at least one day from the previous month 
            if (daysFromLastMonth <= 0) { 
                daysFromLastMonth += 7;
            } 
            return threadCalendar.AddDays(firstDayOfMonth, -daysFromLastMonth);
        }

 
        /// 
        ///  
        private string GetCalendarButtonText(string eventArgument, string buttonText, string title, bool showLink, Color foreColor) { 
            if (showLink) {
                StringBuilder sb = new StringBuilder(); 
                sb.Append(""); 
                sb.Append(buttonText); 
                sb.Append("");
                return sb.ToString(); 
            }
            else {
                return buttonText;
            } 
        }
 
 
        /// 
        ///  
        private int GetDefinedStyleMask() {

            // Selected is always defined because it has default effects
            int styleMask = STYLEMASK_SELECTED; 

            if (dayStyle != null && !dayStyle.IsEmpty) 
                styleMask |= STYLEMASK_DAY; 
            if (todayDayStyle != null && !todayDayStyle.IsEmpty)
                styleMask |= STYLEMASK_TODAY; 
            if (otherMonthDayStyle != null && !otherMonthDayStyle.IsEmpty)
                styleMask |= STYLEMASK_OTHERMONTH;
            if (weekendDayStyle != null && !weekendDayStyle.IsEmpty)
                styleMask |= STYLEMASK_WEEKEND; 
            return styleMask;
        } 
 

        ///  
        /// 
        private string GetMonthName(int m, bool bFull) {
            if (bFull) {
                return DateTimeFormatInfo.CurrentInfo.GetMonthName(m); 
            }
            else { 
                return DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(m); 
            }
        } 


        /// 
        /// Determines if a  
        /// contains week selectors.
        ///  
        protected bool HasWeekSelectors(CalendarSelectionMode selectionMode) { 
            return(selectionMode == CalendarSelectionMode.DayWeek
                   || selectionMode == CalendarSelectionMode.DayWeekMonth); 
        }

        private bool IsTheSameYearMonth(DateTime date1, DateTime date2) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized);
#endif 
            return (threadCalendar.GetEra(date1) == threadCalendar.GetEra(date2) && 
                    threadCalendar.GetYear(date1) == threadCalendar.GetYear(date2) &&
                    threadCalendar.GetMonth(date1) == threadCalendar.GetMonth(date2)); 
        }

        private bool IsMinSupportedYearMonth(DateTime date) {
#if DEBUG 
            Debug.Assert(threadCalendarInitialized);
#endif 
            return IsTheSameYearMonth(minSupportedDate, date); 
        }
 
        private bool IsMaxSupportedYearMonth(DateTime date) {
#if DEBUG
            Debug.Assert(threadCalendarInitialized);
#endif 
            return IsTheSameYearMonth(maxSupportedDate, date);
        } 
 
        /// 
        ///  
        /// Loads a saved state of the . 
        /// 
        protected override void LoadViewState(object savedState) {
            if (savedState != null) { 
                object[] myState = (object[])savedState;
 
                if (myState[0] != null) 
                    base.LoadViewState(myState[0]);
                if (myState[1] != null) 
                    ((IStateManager)TitleStyle).LoadViewState(myState[1]);
                if (myState[2] != null)
                    ((IStateManager)NextPrevStyle).LoadViewState(myState[2]);
                if (myState[3] != null) 
                    ((IStateManager)DayStyle).LoadViewState(myState[3]);
                if (myState[4] != null) 
                    ((IStateManager)DayHeaderStyle).LoadViewState(myState[4]); 
                if (myState[5] != null)
                    ((IStateManager)TodayDayStyle).LoadViewState(myState[5]); 
                if (myState[6] != null)
                    ((IStateManager)WeekendDayStyle).LoadViewState(myState[6]);
                if (myState[7] != null)
                    ((IStateManager)OtherMonthDayStyle).LoadViewState(myState[7]); 
                if (myState[8] != null)
                    ((IStateManager)SelectedDayStyle).LoadViewState(myState[8]); 
                if (myState[9] != null) 
                    ((IStateManager)SelectorStyle).LoadViewState(myState[9]);
 
                ArrayList selDates = (ArrayList)ViewState["SD"];
                if (selDates != null) {
                    dateList = selDates;
                    selectedDates = null;   // reset wrapper collection 
                }
 
            } 
        }
 

        /// 
        /// 
        ///    Marks the starting point to begin tracking and saving changes to the 
        ///       control as part of the control viewstate.
        ///  
        protected override void TrackViewState() { 
            base.TrackViewState();
 
            if (titleStyle != null)
                ((IStateManager)titleStyle).TrackViewState();
            if (nextPrevStyle != null)
                ((IStateManager)nextPrevStyle).TrackViewState(); 
            if (dayStyle != null)
                ((IStateManager)dayStyle).TrackViewState(); 
            if (dayHeaderStyle != null) 
                ((IStateManager)dayHeaderStyle).TrackViewState();
            if (todayDayStyle != null) 
                ((IStateManager)todayDayStyle).TrackViewState();
            if (weekendDayStyle != null)
                ((IStateManager)weekendDayStyle).TrackViewState();
            if (otherMonthDayStyle != null) 
                ((IStateManager)otherMonthDayStyle).TrackViewState();
            if (selectedDayStyle != null) 
                ((IStateManager)selectedDayStyle).TrackViewState(); 
            if (selectorStyle != null)
                ((IStateManager)selectorStyle).TrackViewState(); 
        }


        ///  
        /// 
        private int NumericFirstDayOfWeek() { 
            // Used globalized value by default 
            return(FirstDayOfWeek == FirstDayOfWeek.Default)
            ? (int) DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek 
            : (int) FirstDayOfWeek;
        }

 
        /// 
        /// Raises the event for a . 
        ///  
        protected virtual void OnDayRender(TableCell cell, CalendarDay day) {
            DayRenderEventHandler handler = (DayRenderEventHandler)Events[EventDayRender]; 
            if (handler != null) {
                int absoluteDay = day.Date.Subtract(baseDate).Days;

                // VSWhidbey 215383: We return null for selectUrl if a control is not in 
                // the page control tree.
                string selectUrl = null; 
                Page page = Page; 
                if (page != null) {
                    string eventArgument = absoluteDay.ToString(CultureInfo.InvariantCulture); 
                    selectUrl = Page.ClientScript.GetPostBackClientHyperlink(this, eventArgument, true);
                }
                handler(this, new DayRenderEventArgs(cell, day, selectUrl));
            } 
        }
 
#if SHIPPINGADAPTERS 
        // A wrapper to raise the SelectionChangedEvent when a date is selected
        // by the user.  This can be called by adapters when they have 
        // collected the selected date.
        internal void RaiseSelectionChangedEvent() {
            OnSelectionChanged();
        } 
#endif
 
 
        /// 
        /// Raises the event for a . 
        /// 
        protected virtual void OnSelectionChanged() {
            EventHandler handler = (EventHandler)Events[EventSelectionChanged];
            if (handler != null) { 
                handler(this, EventArgs.Empty);
            } 
        } 

 
        /// 
        /// Raises the event for a .
        /// 
        protected virtual void OnVisibleMonthChanged(DateTime newDate, DateTime previousDate) { 
            MonthChangedEventHandler handler = (MonthChangedEventHandler)Events[EventVisibleMonthChanged];
            if (handler != null) { 
                handler(this, new MonthChangedEventArgs(newDate, previousDate)); 
            }
        } 


        /// 
        ///  
        /// Raises events on post back for the  control.
        ///  
        protected virtual void RaisePostBackEvent(string eventArgument) { 

            ValidateEvent(UniqueID, eventArgument); 

            if(_adapter != null) {
                IPostBackEventHandler pbeh = _adapter as IPostBackEventHandler;
                if (pbeh != null) { 
                    pbeh.RaisePostBackEvent(eventArgument);
                } 
            } else { 

                if (String.Compare(eventArgument, 0, NAVIGATE_MONTH_COMMAND, 0, NAVIGATE_MONTH_COMMAND.Length, StringComparison.Ordinal) == 0) { 
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the
                    // base date.
                    DateTime oldDate = VisibleDate;
                    if (oldDate.Equals(DateTime.MinValue)) { 
                        oldDate = TodaysDate;
                    } 
                    int newDateDiff = Int32.Parse(eventArgument.Substring(NAVIGATE_MONTH_COMMAND.Length), CultureInfo.InvariantCulture); 
                    VisibleDate = baseDate.AddDays(newDateDiff);
                    if (VisibleDate == DateTime.MinValue) { 
                        // MinValue would make the calendar shows today's month instead because it
                        // is the default value of VisibleDate property, so we add a day to keep
                        // showing the first supported month.
                        // We assume the first supported month has more than one day. 
                        VisibleDate = DateTimeFormatInfo.CurrentInfo.Calendar.AddDays(VisibleDate, 1);
                    } 
                    OnVisibleMonthChanged(VisibleDate, oldDate); 
                }
                else if (String.Compare(eventArgument, 0, SELECT_RANGE_COMMAND, 0, SELECT_RANGE_COMMAND.Length, StringComparison.Ordinal) == 0) { 
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the
                    // number of days to select.
                    int rangeValue = Int32.Parse(eventArgument.Substring(SELECT_RANGE_COMMAND.Length), CultureInfo.InvariantCulture); 
                    int dayDiff = rangeValue / 100;
                    int dayRange = rangeValue % 100; 
                    if (dayRange < 1) { 
                        dayRange = 100 + dayRange;
                        dayDiff -= 1; 
                    }
                    DateTime dt = baseDate.AddDays(dayDiff);
                    SelectRange(dt, dt.AddDays(dayRange - 1));
                } 
                else {
                    // Single day selection. This is just a number which is the day difference from the base date. 
                    int dayDiff = Int32.Parse(eventArgument, CultureInfo.InvariantCulture); 
                    DateTime dt = baseDate.AddDays(dayDiff);
                    SelectRange(dt, dt); 
                }
            }
        }
 

        void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) { 
            RaisePostBackEvent(eventArgument); 
        }
 

        /// 
        protected internal override void OnPreRender(EventArgs e) {
            base.OnPreRender(e); 
            if (Page != null) {
                Page.RegisterPostBackScript(); 
            } 
        }
 

        /// 
        /// 
        /// Displays the  control on the client. 
        /// 
        protected internal override void Render(HtmlTextWriter writer) { 
            threadCalendar = DateTimeFormatInfo.CurrentInfo.Calendar; 
            minSupportedDate = threadCalendar.MinSupportedDateTime;
            maxSupportedDate = threadCalendar.MaxSupportedDateTime; 
#if DEBUG
            threadCalendarInitialized = true;
#endif
            DateTime visibleDate = EffectiveVisibleDate(); 
            DateTime firstDay = FirstCalendarDay(visibleDate);
            CalendarSelectionMode selectionMode = SelectionMode; 
 
            // Make sure we are in a form tag with runat=server.
            if (Page != null) { 
                Page.VerifyRenderingInServerForm(this);
            }

            // We only want to display the link if we have a page, or if we are on the design surface 
            // If we can stops links being active on the Autoformat dialog, then we can remove this these checks.
            Page page = Page; 
            bool buttonsActive; 
            if (page == null || DesignMode) {
                buttonsActive = false; 
            }
            else {
                buttonsActive = IsEnabled;
            } 

            defaultForeColor = ForeColor; 
            if (defaultForeColor == Color.Empty) { 
                defaultForeColor = DefaultForeColor;
            } 
            defaultButtonColorText = ColorTranslator.ToHtml(defaultForeColor);

            Table table = new Table();
 
            if (ID != null) {
                table.ID = ClientID; 
            } 
            table.CopyBaseAttributes(this);
            if (ControlStyleCreated) { 
                table.ApplyStyle(ControlStyle);
            }
            table.Width = Width;
            table.Height = Height; 
            table.CellPadding = CellPadding;
            table.CellSpacing = CellSpacing; 
 
            // default look
            if ((ControlStyleCreated == false) || 
                (ControlStyle.IsSet(System.Web.UI.WebControls.Style.PROP_BORDERWIDTH) == false) ||
                BorderWidth.Equals(Unit.Empty)) {
                table.BorderWidth = Unit.Pixel(1);
            } 

            if (ShowGridLines) { 
                table.GridLines = GridLines.Both; 
            }
            else { 
                table.GridLines = GridLines.None;
            }

            bool useAccessibleHeader = UseAccessibleHeader; 
            if (useAccessibleHeader) {
                if (table.Attributes["title"] == null) { 
                    table.Attributes["title"] = SR.GetString(SR.Calendar_TitleText); 
                }
            } 

            string caption = Caption;
            if (caption.Length > 0) {
                table.Caption = caption; 
                table.CaptionAlign = CaptionAlign;
            } 
 
            table.RenderBeginTag(writer);
 
            if (ShowTitle) {
                RenderTitle(writer, visibleDate, selectionMode, buttonsActive, useAccessibleHeader);
            }
 
            if (ShowDayHeader) {
                RenderDayHeader(writer, visibleDate, selectionMode, buttonsActive, useAccessibleHeader); 
            } 

            RenderDays(writer, firstDay, visibleDate, selectionMode, buttonsActive, useAccessibleHeader); 

            table.RenderEndTag(writer);
        }
 
        private void RenderCalendarCell(HtmlTextWriter writer, TableItemStyle style, string text, string title, bool hasButton, string eventArgument) {
            style.AddAttributesToRender(writer, this); 
            writer.RenderBeginTag(HtmlTextWriterTag.Td); 

            if (hasButton) { 

                // render the button
                Color foreColor = style.ForeColor;
                writer.Write(""); 
                writer.Write(text);
                writer.Write("");
            }
            else { 
                writer.Write(text);
            } 
 
            writer.RenderEndTag();
        } 

        private void RenderCalendarHeaderCell(HtmlTextWriter writer, TableItemStyle style, string text, string abbrText) {
            style.AddAttributesToRender(writer, this);
            writer.AddAttribute("abbr", abbrText); 
            writer.AddAttribute("scope", "col");
            writer.RenderBeginTag(HtmlTextWriterTag.Th); 
            writer.Write(text); 
            writer.RenderEndTag();
        } 


        /// 
        ///  
        private void RenderDayHeader(HtmlTextWriter writer, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) {
 
            writer.Write(ROWBEGINTAG); 

            DateTimeFormatInfo dtf = DateTimeFormatInfo.CurrentInfo; 

            if (HasWeekSelectors(selectionMode)) {
                TableItemStyle monthSelectorStyle = new TableItemStyle();
                monthSelectorStyle.HorizontalAlign = HorizontalAlign.Center; 
                // add the month selector button if required;
                if (selectionMode == CalendarSelectionMode.DayWeekMonth) { 
 
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the 
                    // number of days to select.
                    int startOffset = visibleDate.Subtract(baseDate).Days;
                    int monthLength = threadCalendar.GetDaysInMonth(threadCalendar.GetYear(visibleDate), threadCalendar.GetMonth(visibleDate), threadCalendar.GetEra(visibleDate));
                    if (IsMinSupportedYearMonth(visibleDate)) { 
                        // The first supported month might not start with day 1
                        // (e.g. Sept 8 is the first supported date of JapaneseCalendar) 
                        monthLength = monthLength - threadCalendar.GetDayOfMonth(visibleDate) + 1; 
                    }
                    else if (IsMaxSupportedYearMonth(visibleDate)) { 
                        // The last supported month might not have all days supported in that calendar month
                        // (e.g. April 3 is the last supported date of HijriCalendar)
                        monthLength = threadCalendar.GetDayOfMonth(maxSupportedDate);
                    } 

                    string monthSelectKey = SELECT_RANGE_COMMAND + ((startOffset * 100) + monthLength).ToString(CultureInfo.InvariantCulture); 
                    monthSelectorStyle.CopyFrom(SelectorStyle); 

                    string selectMonthTitle = null; 
                    if (useAccessibleHeader) {
                        selectMonthTitle = SR.GetString(SR.Calendar_SelectMonthTitle);
                    }
                    RenderCalendarCell(writer, monthSelectorStyle, SelectMonthText, selectMonthTitle, buttonsActive, monthSelectKey); 
                }
                else { 
                    // otherwise make it look like the header row 
                    monthSelectorStyle.CopyFrom(DayHeaderStyle);
                    RenderCalendarCell(writer, monthSelectorStyle, string.Empty, null, false, null); 
                }
            }

            TableItemStyle dayNameStyle = new TableItemStyle(); 
            dayNameStyle.HorizontalAlign = HorizontalAlign.Center;
            dayNameStyle.CopyFrom(DayHeaderStyle); 
            DayNameFormat dayNameFormat = DayNameFormat; 

            int numericFirstDay = NumericFirstDayOfWeek(); 
            for (int i = numericFirstDay; i < numericFirstDay + 7; i++) {
                string dayName;
                int dayOfWeek = i % 7;
                switch (dayNameFormat) { 
                    case DayNameFormat.FirstLetter:
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek).Substring(0, 1); 
                        break; 
                    case DayNameFormat.FirstTwoLetters:
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek).Substring(0, 2); 
                        break;
                    case DayNameFormat.Full:
                        dayName = dtf.GetDayName((DayOfWeek)dayOfWeek);
                        break; 
                    case DayNameFormat.Short:
                        dayName = dtf.GetAbbreviatedDayName((DayOfWeek)dayOfWeek); 
                        break; 
                    case DayNameFormat.Shortest:
                        dayName = dtf.GetShortestDayName((DayOfWeek)dayOfWeek); 
                        break;
                    default:
                        Debug.Assert(false, "Unknown DayNameFormat value!");
                        goto case DayNameFormat.Short; 
                }
 
                if (useAccessibleHeader) { 
                    string fullDayName = dtf.GetDayName((DayOfWeek)dayOfWeek);
                    RenderCalendarHeaderCell(writer, dayNameStyle, dayName, fullDayName); 
                }
                else {
                    RenderCalendarCell(writer, dayNameStyle, dayName, null, false, null);
                } 
            }
            writer.Write(ROWENDTAG); 
        } 

 
        /// 
        /// 
        private void RenderDays(HtmlTextWriter writer, DateTime firstDay, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) {
            // Now add the rows for the actual days 

            DateTime d = firstDay; 
            TableItemStyle weekSelectorStyle = null; 
            Unit defaultWidth;
            bool hasWeekSelectors = HasWeekSelectors(selectionMode); 
            if (hasWeekSelectors) {
                weekSelectorStyle = new TableItemStyle();
                weekSelectorStyle.Width = Unit.Percentage(12);
                weekSelectorStyle.HorizontalAlign = HorizontalAlign.Center; 
                weekSelectorStyle.CopyFrom(SelectorStyle);
                defaultWidth = Unit.Percentage(12); 
            } 
            else {
                defaultWidth = Unit.Percentage(14); 
            }

            // This determines whether we need to call DateTime.ToString for each day. The only culture/calendar
            // that requires this for now is the HebrewCalendar. 
            bool usesStandardDayDigits = !(threadCalendar is HebrewCalendar);
 
            // This determines whether we can write out cells directly, or whether we have to create whole 
            // TableCell objects for each day.
            bool hasRenderEvent = (this.GetType() != typeof(Calendar) 
                                   || Events[EventDayRender] != null);

            TableItemStyle [] cellStyles = new TableItemStyle[16];
            int definedStyleMask = GetDefinedStyleMask(); 
            DateTime todaysDate = TodaysDate;
            string selectWeekText = SelectWeekText; 
            bool daysSelectable = buttonsActive && (selectionMode != CalendarSelectionMode.None); 
            int visibleDateMonth = threadCalendar.GetMonth(visibleDate);
            int absoluteDay = firstDay.Subtract(baseDate).Days; 

            // VSWhidbey 480155: flag to indicate if forecolor needs to be set
            // explicitly in design mode to mimic runtime rendering with the
            // limitation of not supporting CSS class color setting. 
            bool inDesignSelectionMode = (DesignMode && SelectionMode != CalendarSelectionMode.None);
 
            //----------------------------------------------------------------- 
            // VSWhidbey 366243: The following variables are for boundary cases
            // such as the current visible month is the first or the last 
            // supported month.  They are used in the 'for' loops below.

            // For the first supported month, calculate how many days to
            // skip at the beginning of the first month.  E.g. JapaneseCalendar 
            // starts at Sept 8.
            int numOfFirstDaysToSkip = 0; 
            if (IsMinSupportedYearMonth(visibleDate)) { 
                numOfFirstDaysToSkip = (int)threadCalendar.GetDayOfWeek(firstDay) - NumericFirstDayOfWeek();
                // If negative, it simply means the the index of the starting 
                // day name is greater than the day name of the first supported
                // date.  We add back 7 to get the number of days to skip.
                if (numOfFirstDaysToSkip < 0) {
                    numOfFirstDaysToSkip += 7; 
                }
            } 
            Debug.Assert(numOfFirstDaysToSkip < 7); 

            // For the last or second last supported month, initialize variables 
            // to identify the last supported date of the current calendar.
            // e.g. The last supported date of HijriCalendar is April 3.  When
            // the second last monthh is shown, it can be the case that not all
            // cells will be filled up. 
            bool passedLastSupportedDate = false;
            DateTime secondLastMonth = threadCalendar.AddMonths(maxSupportedDate, -1); 
            bool lastOrSecondLastMonth = (IsMaxSupportedYearMonth(visibleDate) || 
                                IsTheSameYearMonth(secondLastMonth, visibleDate));
            //----------------------------------------------------------------- 

            for (int iRow = 0; iRow < 6; iRow++) {
                if (passedLastSupportedDate) {
                    break; 
                }
 
                writer.Write(ROWBEGINTAG); 

                // add week selector column and button if required 
                if (hasWeekSelectors) {
                    // Range selection. The command starts with an "R". The remainder is an integer. When divided by 100
                    // the result is the day difference from the base date of the first day, and the remainder is the
                    // number of days to select. 
                    int dayDiffParameter = (absoluteDay * 100) + 7;
 
                    // Adjust the dayDiff for the first or the last supported month 
                    if (numOfFirstDaysToSkip > 0) {
                        dayDiffParameter -= numOfFirstDaysToSkip; 
                    }
                    else if (lastOrSecondLastMonth) {
                        int daysFromLastDate = maxSupportedDate.Subtract(d).Days;
                        if (daysFromLastDate < 6) { 
                            dayDiffParameter -= (6 - daysFromLastDate);
                        } 
                    } 
                    string weekSelectKey = SELECT_RANGE_COMMAND + dayDiffParameter.ToString(CultureInfo.InvariantCulture);
 
                    string selectWeekTitle = null;
                    if (useAccessibleHeader) {
                        int weekOfMonth = iRow + 1;
                        selectWeekTitle = SR.GetString(SR.Calendar_SelectWeekTitle, weekOfMonth.ToString(CultureInfo.InvariantCulture)); 
                    }
                    RenderCalendarCell(writer, weekSelectorStyle, selectWeekText, selectWeekTitle, buttonsActive, weekSelectKey); 
                } 

                for (int iDay = 0; iDay < 7; iDay++) { 

                    // Render empty cells for special cases to handle the first
                    // or last supported month.
                    if (numOfFirstDaysToSkip > 0) { 
                        iDay += numOfFirstDaysToSkip;
                        for ( ; numOfFirstDaysToSkip > 0; numOfFirstDaysToSkip--) { 
                            writer.RenderBeginTag(HtmlTextWriterTag.Td); 
                            writer.RenderEndTag();
                        } 
                    }
                    else if (passedLastSupportedDate) {
                        for ( ; iDay < 7; iDay++) {
                            writer.RenderBeginTag(HtmlTextWriterTag.Td); 
                            writer.RenderEndTag();
                        } 
                        break; 
                    }
 
                    int dayOfWeek = (int)threadCalendar.GetDayOfWeek(d);
                    int dayOfMonth = threadCalendar.GetDayOfMonth(d);
                    string dayNumberText;
                    if ((dayOfMonth <= cachedNumberMax) && usesStandardDayDigits) { 
                        dayNumberText = cachedNumbers[dayOfMonth];
                    } 
                    else { 
                        dayNumberText = d.ToString("dd", CultureInfo.CurrentCulture);
                    } 

                    CalendarDay day = new CalendarDay(d,
                                                      (dayOfWeek == 0 || dayOfWeek == 6), // IsWeekend
                                                      d.Equals(todaysDate), // IsToday 
                                                      (selectedDates != null) && selectedDates.Contains(d), // IsSelected
                                                      threadCalendar.GetMonth(d) != visibleDateMonth, // IsOtherMonth 
                                                      dayNumberText // Number Text 
                                                      );
 
                    int styleMask = STYLEMASK_DAY;
                    if (day.IsSelected)
                        styleMask |= STYLEMASK_SELECTED;
                    if (day.IsOtherMonth) 
                        styleMask |= STYLEMASK_OTHERMONTH;
                    if (day.IsToday) 
                        styleMask |= STYLEMASK_TODAY; 
                    if (day.IsWeekend)
                        styleMask |= STYLEMASK_WEEKEND; 
                    int dayStyleMask = definedStyleMask  & styleMask;
                    // determine the unique portion of the mask for the current calendar,
                    // which will strip out the day style bit
                    int dayStyleID = dayStyleMask & STYLEMASK_UNIQUE; 

                    TableItemStyle cellStyle = cellStyles[dayStyleID]; 
                    if (cellStyle == null) { 
                        cellStyle = new TableItemStyle();
                        SetDayStyles(cellStyle, dayStyleMask, defaultWidth); 
                        cellStyles[dayStyleID] = cellStyle;
                    }

 
                    string dayTitle = null;
                    if (useAccessibleHeader) { 
                        dayTitle = d.ToString("m", CultureInfo.CurrentCulture); 
                    }
 
                    if (hasRenderEvent) {

                        TableCell cdc = new TableCell();
                        cdc.ApplyStyle(cellStyle); 

                        LiteralControl dayContent = new LiteralControl(dayNumberText); 
                        cdc.Controls.Add(dayContent); 

                        day.IsSelectable = daysSelectable; 

                        OnDayRender(cdc, day);

                        // refresh the day content 
                        dayContent.Text = GetCalendarButtonText(absoluteDay.ToString(CultureInfo.InvariantCulture),
                                                                dayNumberText, 
                                                                dayTitle, 
                                                                buttonsActive && day.IsSelectable,
                                                                cdc.ForeColor); 
                        cdc.RenderControl(writer);

                    }
                    else { 
                        // VSWhidbey 480155: In design mode we render days as
                        // texts instead of links so CSS class color setting is 
                        // supported.  But this differs in runtime rendering 
                        // where CSS class color setting is not supported.  To
                        // correctly mimic the forecolor of runtime rendering in 
                        // design time, the default color, which is used in
                        // runtime rendering, is explicitly set in this case.
                        if (inDesignSelectionMode && cellStyle.ForeColor.IsEmpty) {
                            cellStyle.ForeColor = defaultForeColor; 
                        }
 
                        RenderCalendarCell(writer, cellStyle, dayNumberText, dayTitle, daysSelectable, absoluteDay.ToString(CultureInfo.InvariantCulture)); 
                    }
 
                    Debug.Assert(!passedLastSupportedDate);
                    if (lastOrSecondLastMonth && d.Month == maxSupportedDate.Month && d.Day == maxSupportedDate.Day) {
                        passedLastSupportedDate = true;
                    } 
                    else {
                        d = threadCalendar.AddDays(d, 1); 
                        absoluteDay++; 
                    }
                } 
                writer.Write(ROWENDTAG);
            }
        }
 

        ///  
        ///  
        private void RenderTitle(HtmlTextWriter writer, DateTime visibleDate, CalendarSelectionMode selectionMode, bool buttonsActive, bool useAccessibleHeader) {
            writer.Write(ROWBEGINTAG); 

            TableCell titleCell = new TableCell();
            Table titleTable = new Table();
 
            // default title table/cell styles
            titleCell.ColumnSpan = HasWeekSelectors(selectionMode) ? 8 : 7; 
            titleCell.BackColor = Color.Silver; 
            titleTable.GridLines = GridLines.None;
            titleTable.Width = Unit.Percentage(100); 
            titleTable.CellSpacing = 0;

            TableItemStyle titleStyle = TitleStyle;
            ApplyTitleStyle(titleCell, titleTable, titleStyle); 

            titleCell.RenderBeginTag(writer); 
            titleTable.RenderBeginTag(writer); 
            writer.Write(ROWBEGINTAG);
 
            NextPrevFormat nextPrevFormat = NextPrevFormat;

            TableItemStyle nextPrevStyle = new TableItemStyle();
            nextPrevStyle.Width = Unit.Percentage(15); 
            nextPrevStyle.CopyFrom(NextPrevStyle);
            if (ShowNextPrevMonth) { 
                if (IsMinSupportedYearMonth(visibleDate)) { 
                    writer.RenderBeginTag(HtmlTextWriterTag.Td);
                    writer.RenderEndTag(); 
                }
                else {
                    string prevMonthText;
                    if (nextPrevFormat == NextPrevFormat.ShortMonth || nextPrevFormat == NextPrevFormat.FullMonth) { 
                        int monthNo = threadCalendar.GetMonth(threadCalendar.AddMonths(visibleDate, - 1));
                        prevMonthText = GetMonthName(monthNo, (nextPrevFormat == NextPrevFormat.FullMonth)); 
                    } 
                    else {
                        prevMonthText = PrevMonthText; 
                    }
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the
                    // base date.
                    DateTime prevMonthDate; 

                    // VSWhidbey 366243: Some calendar's min supported date is 
                    // not the first day of the month (e.g. JapaneseCalendar. 
                    // So if we are setting the second supported month, the prev
                    // month link should always point to the first supported 
                    // date instead of the first day of the previous month.
                    DateTime secondSupportedMonth = threadCalendar.AddMonths(minSupportedDate, 1);
                    if (IsTheSameYearMonth(secondSupportedMonth, visibleDate)) {
                        prevMonthDate = minSupportedDate; 
                    }
                    else { 
                        prevMonthDate = threadCalendar.AddMonths(visibleDate, -1); 
                    }
 
                    string prevMonthKey = NAVIGATE_MONTH_COMMAND + (prevMonthDate.Subtract(baseDate)).Days.ToString(CultureInfo.InvariantCulture);

                    string previousMonthTitle = null;
                    if (useAccessibleHeader) { 
                        previousMonthTitle = SR.GetString(SR.Calendar_PreviousMonthTitle);
                    } 
                    RenderCalendarCell(writer, nextPrevStyle, prevMonthText, previousMonthTitle, buttonsActive, prevMonthKey); 
                }
            } 


            TableItemStyle cellMainStyle = new TableItemStyle();
 
            if (titleStyle.HorizontalAlign != HorizontalAlign.NotSet) {
                cellMainStyle.HorizontalAlign = titleStyle.HorizontalAlign; 
            } 
            else {
                cellMainStyle.HorizontalAlign = HorizontalAlign.Center; 
            }
            cellMainStyle.Wrap = titleStyle.Wrap;
            cellMainStyle.Width = Unit.Percentage(70);
 
            string titleText;
 
            switch (TitleFormat) { 
                case TitleFormat.Month:
                    titleText = visibleDate.ToString("MMMM", CultureInfo.CurrentCulture); 
                    break;
                case TitleFormat.MonthYear:
                    string titlePattern = DateTimeFormatInfo.CurrentInfo.YearMonthPattern;
                    // Some cultures have a comma in their YearMonthPattern, which does not look 
                    // right in a calendar. Use a fixed pattern for those.
                    if (titlePattern.IndexOf(',') >= 0) { 
                        titlePattern = "MMMM yyyy"; 
                    }
                    titleText = visibleDate.ToString(titlePattern, CultureInfo.CurrentCulture); 
                    break;
                default:
                    Debug.Assert(false, "Unknown TitleFormat value!");
                    goto case TitleFormat.MonthYear; 
            }
            RenderCalendarCell(writer, cellMainStyle, titleText, null, false, null); 
 
            if (ShowNextPrevMonth) {
                if (IsMaxSupportedYearMonth(visibleDate)) { 
                    writer.RenderBeginTag(HtmlTextWriterTag.Td);
                    writer.RenderEndTag();
                }
                else { 
                    // Style for this one is identical bar
                    nextPrevStyle.HorizontalAlign = HorizontalAlign.Right; 
                    string nextMonthText; 
                    if (nextPrevFormat == NextPrevFormat.ShortMonth || nextPrevFormat == NextPrevFormat.FullMonth) {
                        int monthNo = threadCalendar.GetMonth(threadCalendar.AddMonths(visibleDate, 1)); 
                        nextMonthText = GetMonthName(monthNo, (nextPrevFormat == NextPrevFormat.FullMonth));
                    }
                    else {
                        nextMonthText = NextMonthText; 
                    }
                    // Month navigation. The command starts with a "V" and the remainder is day difference from the 
                    // base date. 
                    DateTime nextMonthDate = threadCalendar.AddMonths(visibleDate, 1);
                    string nextMonthKey = NAVIGATE_MONTH_COMMAND + (nextMonthDate.Subtract(baseDate)).Days.ToString(CultureInfo.InvariantCulture); 

                    string nextMonthTitle = null;
                    if (useAccessibleHeader) {
                        nextMonthTitle = SR.GetString(SR.Calendar_NextMonthTitle); 
                    }
                    RenderCalendarCell(writer, nextPrevStyle, nextMonthText, nextMonthTitle, buttonsActive, nextMonthKey); 
                } 
            }
            writer.Write(ROWENDTAG); 
            titleTable.RenderEndTag(writer);
            titleCell.RenderEndTag(writer);
            writer.Write(ROWENDTAG);
 
        }
 
 
        /// 
        ///  
        /// Stores the state of the System.Web.UI.WebControls.Calender.
        /// 
        protected override object SaveViewState() {
            if (SelectedDates.Count > 0) 
                ViewState["SD"] = dateList;
 
            object[] myState = new object[10]; 

            myState[0] = base.SaveViewState(); 
            myState[1] = (titleStyle != null) ? ((IStateManager)titleStyle).SaveViewState() : null;
            myState[2] = (nextPrevStyle != null) ? ((IStateManager)nextPrevStyle).SaveViewState() : null;
            myState[3] = (dayStyle != null) ? ((IStateManager)dayStyle).SaveViewState() : null;
            myState[4] = (dayHeaderStyle != null) ? ((IStateManager)dayHeaderStyle).SaveViewState() : null; 
            myState[5] = (todayDayStyle != null) ? ((IStateManager)todayDayStyle).SaveViewState() : null;
            myState[6] = (weekendDayStyle != null) ? ((IStateManager)weekendDayStyle).SaveViewState() : null; 
            myState[7] = (otherMonthDayStyle != null) ? ((IStateManager)otherMonthDayStyle).SaveViewState() : null; 
            myState[8] = (selectedDayStyle != null) ? ((IStateManager)selectedDayStyle).SaveViewState() : null;
            myState[9] = (selectorStyle != null) ? ((IStateManager)selectorStyle).SaveViewState() : null; 

            for (int i = 0; i
        ///  
        private void SetDayStyles(TableItemStyle style, int styleMask, Unit defaultWidth) {

            // default day styles
            style.Width = defaultWidth; 
            style.HorizontalAlign = HorizontalAlign.Center;
 
            if ((styleMask & STYLEMASK_DAY) != 0) { 
                style.CopyFrom(DayStyle);
            } 
            if ((styleMask & STYLEMASK_WEEKEND) != 0) {
                style.CopyFrom(WeekendDayStyle);
            }
            if ((styleMask & STYLEMASK_OTHERMONTH) != 0) { 
                style.CopyFrom(OtherMonthDayStyle);
            } 
            if ((styleMask & STYLEMASK_TODAY) != 0) { 
                style.CopyFrom(TodayDayStyle);
            } 

            if ((styleMask & STYLEMASK_SELECTED) != 0) {
                // default selected day style
                style.ForeColor = Color.White; 
                style.BackColor = Color.Silver;
 
                style.CopyFrom(SelectedDayStyle); 
            }
        } 
    }
}

 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK