In this article I’ll be explaining how to create a simple calendar date selector using three DropDownLists in ASP.Net. The three DropDownLists will correspond to Day, Month and Year.
What’s the need of creating a user control when there are ready made calendars available? The answer is that quite often for end users it seems difficult to use the calendar controls.
Three Dropdownlists Custom Calendar Date selector

So let’s start building our Custom Date Selector Calendar Control
Building the User Control
First we’ll start by creating the HTML Markup and adding the controls to it
Year:<asp:DropDownList ID="ddlYear" runat="server" onchange = "PopulateDays()" />
Month:<asp:DropDownList ID="ddlMonth" runat="server" onchange = "PopulateDays()" />
Day:<asp:DropDownList ID="ddlDay" runat="server" />
<br /> 
<asp:CustomValidator ID="Validator" runat="server" ErrorMessage="* Required"
ClientValidationFunction = "Validate" />

As you’ll notice above the Markup is very simple. I have added 3 DropDownLists and a Custom Validator that will validate the dates. I am also calling some JavaScript functions which I’ll be describing later.
Then you’ll need to add a new user control to your project and add the following properties to it
C#
private int Day
{
    get
    {
        if (Request.Form[ddlDay.UniqueID] != null)
        {
            return int.Parse(Request.Form[ddlDay.UniqueID]);
        }
        else
        {
            return int.Parse(ddlDay.SelectedItem.Value);
        }
    }
    set
    {
        this.PopulateDay();
        ddlDay.ClearSelection();
        ddlDay.Items.FindByValue(value.ToString()).Selected = true;
    }
}
private int Month
{
    get
    {
        return int.Parse(ddlMonth.SelectedItem.Value);
    }
    set
    {
        this.PopulateMonth();
        ddlMonth.ClearSelection();
        ddlMonth.Items.FindByValue(value.ToString()).Selected = true;
    }
}
private int Year
{
    get
    {
        return int.Parse(ddlYear.SelectedItem.Value);
    }
    set
    {
        this.PopulateYear();
        ddlYear.ClearSelection();
        ddlYear.Items.FindByValue(value.ToString()).Selected = true;
    }
}
 
public DateTime SelectedDate
{
    get
    {
        try
        {
            return DateTime.Parse(this.Month + "/" + this.Day + "/" + this.Year);
        }
        catch
        {
            return DateTime.MinValue;
        }
    }
    set
    {
        if (!value.Equals(DateTime.MinValue))
        {
            this.Year = value.Year;
            this.Month = value.Month;
            this.Day = value.Day;
        }
    }
}
 
VB.Net
 
Private Property Day() As Integer
        Get
            If (Not (Request.Form(ddlDay.UniqueID)) Is Nothing) Then
                Return Integer.Parse(Request.Form(ddlDay.UniqueID))
            Else
                Return Integer.Parse(ddlDay.SelectedItem.Value)
            End If
        End Get
        Set(ByVal value As Integer)
            Me.PopulateDay()
            ddlDay.ClearSelection()
            ddlDay.Items.FindByValue(value.ToString).Selected = True
        End Set
End Property
 
Private Property Month() As Integer
        Get
            Return Integer.Parse(ddlMonth.SelectedItem.Value)
        End Get
        Set(ByVal value As Integer)
            Me.PopulateMonth()
            ddlMonth.ClearSelection()
            ddlMonth.Items.FindByValue(value.ToString).Selected = True
        End Set
End Property
 
Private Property Year() As Integer
        Get
            Return Integer.Parse(ddlYear.SelectedItem.Value)
        End Get
        Set(ByVal value As Integer)
            Me.PopulateYear()
            ddlYear.ClearSelection()
            ddlYear.Items.FindByValue(value.ToString).Selected = True
        End Set
End Property
 
Public Property SelectedDate() As DateTime
        Get
            Try
                Return DateTime.Parse(Me.Month & "/" & Me.Day & "/" & Me.Year)
            Catch ex As Exception
                Return DateTime.MinValue
            End Try
        End Get
        Set(ByVal value As DateTime)
            If Not value.Equals(DateTime.MinValue) Then
                Me.Year = value.Year
                Me.Month = value.Month
                Me.Day = value.Day
            End If
        End Set
End Property

The above properties will be used to get or set the date in our custom date selector.
Next job is to write some code snippet that will populate our three DropDownLists with Days, Month and Year values. The methods below populate the DropDownLists with Day, Month and Year values
C#
private void PopulateDay()
{
    ddlDay.Items.Clear();
    ListItem lt = new ListItem();
    lt.Text = "DD";
    lt.Value = "0";
    ddlDay.Items.Add(lt);
    int days = DateTime.DaysInMonth(this.Year, this.Month);
    for (int i = 1; i <= days; i++)
    {
        lt = new ListItem();
        lt.Text = i.ToString();
        lt.Value = i.ToString();
        ddlDay.Items.Add(lt);
    }
    ddlDay.Items.FindByValue(DateTime.Now.Day.ToString()).Selected = true;
}
 
private void PopulateMonth()
{
    ddlMonth.Items.Clear();
    ListItem lt = new ListItem();
    lt.Text = "MM";
    lt.Value = "0";
    ddlMonth.Items.Add(lt);
    for (int i = 1; i <= 12; i++)
    {
        lt = new ListItem();
        lt.Text = Convert.ToDateTime(i.ToString() + "/1/1900").ToString("MMMM");
        lt.Value = i.ToString();
        ddlMonth.Items.Add(lt);
    }
    ddlMonth.Items.FindByValue(DateTime.Now.Month.ToString()).Selected = true;
}
 
private void PopulateYear()
{
    ddlYear.Items.Clear();
    ListItem lt = new ListItem();
    lt.Text = "YYYY";
    lt.Value = "0";
    ddlYear.Items.Add(lt);
    for (int i = DateTime.Now.Year; i >= 1950; i--)
    {
        lt = new ListItem();
       lt.Text = i.ToString();
        lt.Value = i.ToString();
        ddlYear.Items.Add(lt);
    }
    ddlYear.Items.FindByValue(DateTime.Now.Year.ToString()).Selected = true;
}
 
VB.Net
Private Sub PopulateDay()
        ddlDay.Items.Clear()
        Dim lt As ListItem = New ListItem
        lt.Text = "DD"
        lt.Value = "0"
        ddlDay.Items.Add(lt)
        Dim days As Integer = DateTime.DaysInMonth(Me.Year, Me.Month)
        Dim i As Integer = 1
        Do While (i <= days)
            lt = New ListItem
            lt.Text = i.ToString
            lt.Value = i.ToString
            ddlDay.Items.Add(lt)
            i = (i + 1)
        Loop
        ddlDay.Items.FindByValue(DateTime.Now.Day.ToString).Selected = True
End Sub
 
Private Sub PopulateMonth()
        ddlMonth.Items.Clear()
        Dim lt As ListItem = New ListItem
        lt.Text = "MM"
        lt.Value = "0"
        ddlMonth.Items.Add(lt)
        Dim i As Integer = 1
        Do While (i <= 12)
            lt = New ListItem
            lt.Text = Convert.ToDateTime((i.ToString + "/1/1900")).ToString("MMMM")
            lt.Value = i.ToString
            ddlMonth.Items.Add(lt)
            i = (i + 1)
        Loop
        ddlMonth.Items.FindByValue(DateTime.Now.Month.ToString).Selected = True
End Sub
 
Private Sub PopulateYear()
        ddlYear.Items.Clear()
        Dim lt As ListItem = New ListItem
        lt.Text = "YYYY"
        lt.Value = "0"
        ddlYear.Items.Add(lt)
        Dim i As Integer = DateTime.Now.Year
        Do While (i >= 1950)
            lt = New ListItem
            lt.Text = i.ToString
            lt.Value = i.ToString
            ddlYear.Items.Add(lt)
            i = (i - 1)
        Loop
        ddlYear.Items.FindByValue(DateTime.Now.Year.ToString).Selected = True
End Sub

Note: You will notice that I am populating the day DropDownList after the Month and Year DropDownLists are populated, the reason for this is that I populate the number of days in month based on the values to the selected month and year.
Once these methods are created we can call them in Page Load event in the following way.
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        if (this.SelectedDate == DateTime.MinValue)
        {
            this.PopulateYear();
            this.PopulateMonth();
            this.PopulateDay();
        }
    }
    else
    {
        if (Request.Form[ddlDay.UniqueID] != null)
        {
            this.PopulateDay();
            ddlDay.ClearSelection();
            ddlDay.Items.FindByValue(Request.Form[ddlDay.UniqueID]).Selected = true;
        }
    }
}

VB.Net
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        If Not IsPostBack Then
            If (Me.SelectedDate = DateTime.MinValue) Then
                Me.PopulateYear()
                Me.PopulateMonth()
                Me.PopulateDay()
            End If
        Else
            If (Not (Request.Form(ddlDay.UniqueID)) Is Nothing) Then
                Me.PopulateDay()
                ddlDay.ClearSelection()
                ddlDay.Items.FindByValue(Request.Form(ddlDay.UniqueID)).Selected = True
            End If
        End If
End Sub

Above when the first time page loads I populate all the three DropDownLists. And when there is PostBack, I have taken care that the selected value of the Day DropDownList is preserved since it is also populated client side and in such cases ViewState doesn’t work.
 
Client Side Operations
Client Side operations are needed since the day DropDownList is populated based on the values of the Month and Year. Thus in other words based on the values of Month and Year it is decided how many days in a month should be present.
<script type="text/javascript">   
function PopulateDays() {
    var ddlMonth = document.getElementById("<%=ddlMonth.ClientID%>");
    var ddlYear = document.getElementById("<%=ddlYear.ClientID%>");
    var ddlDay = document.getElementById("<%=ddlDay.ClientID%>");
    var y = ddlYear.options[ddlYear.selectedIndex].value;
    var m = ddlMonth.options[ddlMonth.selectedIndex].value != 0;
    if (ddlMonth.options[ddlMonth.selectedIndex].value != 0 && ddlYear.options[ddlYear.selectedIndex].value != 0) {
        var dayCount = 32 - new Date(ddlYear.options[ddlYear.selectedIndex].value, ddlMonth.options[ddlMonth.selectedIndex].value - 1, 32).getDate();
        ddlDay.options.length = 0;
        AddOption(ddlDay, "DD", "0");
        for (var i = 1; i <= dayCount; i++) {
            AddOption(ddlDay, i, i);
        }
    }
}
 
function AddOption(ddl, text, value) {
    var opt = document.createElement("OPTION");
    opt.text = text;
    opt.value = value;
    ddl.options.add(opt);
}
 
function Validate(sender, args) {
    var ddlMonth = document.getElementById("<%=ddlMonth.ClientID%>");
    var ddlYear = document.getElementById("<%=ddlYear.ClientID%>");
    var ddlDay = document.getElementById("<%=ddlDay.ClientID%>");
    args.IsValid = (ddlDay.selectedIndex != 0 && ddlMonth.selectedIndex != 0 && ddlYear.selectedIndex != 0)
}
</script>

The PopulateDays function as the name suggests populate the day DropDownList client side based on the values of the Month and Year. This avoids the validation checks for leap years. This method gets called when the month and year DropDownList’s values are changed.
The next method AddOption is a generic method that adds values to a DropDownList.
Finally the Validate method validates the three DropDownLists to verify if the user has selected all the values or not. This method is called up by the Custom Validator.
 
Getting and setting the Date in the Custom Date Selector
Using the SelectedDate property you can easily set and get the Selected Date from the Custom Calendar Date Selector in the following way
C#
//Set Date
ucDateSelector.SelectedDate = DateTime.Parse("05/10/2010");
//Get Date
Response.Write(ucDateSelector.SelectedDate.ToShortDateString());
 
VB.Net
'Set Date
ucDateSelector.SelectedDate = DateTime.Parse("05/10/2010")
 
'Get Date
Response.Write(ucDateSelector.SelectedDate.ToShortDateString)
 
Thus we come to the end of this article. You can download the related source code in VB.Net and C# using the link below
Three Dropdownlists Custom Calendar Dateselector.zip