(c) 2002 Visual Studio Magazine 
Fawcette Technical Publications

Issue: September 2002
Section: Create Localizable Web User Controls
Author: Gerardo Villeda


VB.NET	Create a Date Picker Web User Control
Listing 1	A single module provides the control's necessary functionality, including handling the items in the drop-down lists and all localizable text. The control provides three properties and no public methods. The CultureName property determines the language or cultural settings the control uses to display month names. The SelectedDate property provides access to the current value determined by the user selections. Finally, the CssClass property assigns a style to the control to configure how the control is displayed.

Public MustInherit Class DatePicker
Inherits System.Web.UI.UserControl

	Protected WithEvents cboMonth As _
		System.Web.UI.WebControls.DropDownList
	Protected WithEvents cboDay As _
		System.Web.UI.WebControls.DropDownList
	Protected WithEvents cboYear As _
		System.Web.UI.WebControls.DropDownList
	Protected WithEvents MonthLabel As _
		System.Web.UI.WebControls.Label
	Protected WithEvents DayLabel As _
		System.Web.UI.WebControls.Label
	Protected WithEvents YearLabel As _
		System.Web.UI.WebControls.Label

	Dim strCssClass As String = "CDropDown"

	Public Property CultureName() As String
		Get
			CultureName = CType(ViewState _
				("CultureName"), String)
		End Get
		Set(ByVal Value As String)
			ViewState("CultureName") = Value
			Me.SelectedDate = GetDropDownDate()
			Me.FillDropDownData()
			SetLocalizableStrings()
		End Set
	End Property

	Public Property CssClass() As String
		Get
			CssClass = strCssClass
		End Get
		Set(ByVal Value As String)
			strCssClass = Value
		End Set
	End Property

	Public Property SelectedDate() As Date
		Get
			SelectedDate = CType(ViewState _
				("SelectedDate"), Date)
		End Get
		Set(ByVal Value As Date)
			ViewState("SelectedDate") = Value
		End Set
	End Property

	Private Function GetDropDownDate() As Date
		'If there are items in the combo box, get 
		'their current values or default to current 
		'date
		If (cboMonth.Items.Count > 0) And _
			(cboYear.Items.Count > 0) And _
			(cboDay.Items.Count > 0) Then
			GetDropDownDate = DateSerial _
				(cboYear.SelectedItem.Value, _
				cboMonth.SelectedItem.Value, _
				cboDay.SelectedItem.Value)
		Else
			GetDropDownDate = Now()
		End If
	End Function

	Private Sub Page_Load(ByVal sender As _
		System.Object, ByVal e As _
		System.EventArgs) Handles MyBase.Load
		Dim DateResources As New _
			Resources.ResourceManager _
			("DatePicker.DatePickerStrings", _
			System.Reflection.Assembly. _
			GetExecutingAssembly())
		cboMonth.CssClass = strCssClass
		cboDay.CssClass = strCssClass
		cboYear.CssClass = strCssClass
		'IsPostBack is set to true when we are 
		'returning to the page (or control)
		If (Not IsPostBack) Then
			SelectedDate = GetDropDownDate()
			FillDropDownData()
			SetLocalizableStrings()
		End If
	End Sub

	Private Sub FillDropDownData()
		'If the culture property is empty, use the 
		'value defined for the page.
		If (Me.CultureName = "") Then
			Me.CultureName = Globalization. _
				CultureInfo.CurrentCulture.Name
		End If
		'Create a new culture class with the value 
		'in strCulture
		Dim culture As New _
			System.Globalization.CultureInfo _
			(Me.CultureName)
		Dim dtmTemp As Date
		Dim objItem As ListItem
		Dim intI As Integer

		'Clear items
		cboMonth.Items.Clear()
		cboDay.Items.Clear()
		cboYear.Items.Clear()

		'Add months (select month in SelectedDate)
		For intI = 1 To _
			culture.Calendar.GetMonthsInYear _
			(Me.SelectedDate.Year)
		dtmTemp = New Date(Me.SelectedDate.Year, _
			intI, 1, culture.Calendar)
		objItem = New ListItem(dtmTemp.ToString _
			("MMMM", culture), intI)
		If (Me.SelectedDate.Month = intI) Then
			objItem.Selected = True
		End If
			cboMonth.Items.Add(objItem)
		Next

		'Add days (select day in SelectedDate)
		dtmTemp = DateSerial(0, _
			Me.SelectedDate.Month + 1, 0)
		For intI = 1 To Date.DaysInMonth _
			(Me.SelectedDate.Year, _
			Me.SelectedDate.Month) ' dtmTemp.Day
			objItem = New ListItem(intI, intI)
			If (Me.SelectedDate.Day = intI) Then
				objItem.Selected = True
			End If
			cboDay.Items.Add(objItem)
		Next

		'Add years (select year in SelectedDate)
		For intI = Me.SelectedDate.Year - 5 To _
			Me.SelectedDate.Year + 5
			objItem = New ListItem(intI, intI)
			If (Me.SelectedDate.Year = intI) Then
				objItem.Selected = True
			End If
			cboYear.Items.Add(objItem)
		Next
	End Sub

	Private Sub cboMonth_SelectedIndexChanged _
		(ByVal sender As Object, ByVal e As _
		System.EventArgs) Handles _
		cboMonth.SelectedIndexChanged
		If CInt(cboDay.SelectedItem.Value) <= _
			Me.SelectedDate.DaysInMonth _
			(cboYear.SelectedItem.Value, _
			cboMonth.SelectedItem.Value) Then
			Me.SelectedDate = New _
				Date(cboYear.SelectedItem.Value, _
				cboMonth.SelectedItem.Value, _
				cboDay.SelectedItem.Value)
		Else
			Me.SelectedDate = New Date _
				(cboYear.SelectedItem.Value, _
				cboMonth.SelectedItem.Value, _
				Me.SelectedDate.DaysInMonth _
				(cboYear.SelectedItem.Value, _
				cboMonth.SelectedItem.Value))
		End If
		FillDropDownData()
	End Sub

	Private Sub cboYear_SelectedIndexChanged _
		(ByVal sender As Object, ByVal e As _
		System.EventArgs) Handles _
		cboYear.SelectedIndexChanged
		If CInt(cboDay.SelectedItem.Value) <= _
			Me.SelectedDate.DaysInMonth _
			(cboYear.SelectedItem.Value, _
			cboMonth.SelectedItem.Value) Then
			Me.SelectedDate = New Date _
				(cboYear.SelectedItem.Value, _
				cboMonth.SelectedItem.Value, _
				cboDay.SelectedItem.Value)
		Else
			Me.SelectedDate = New Date _
				(cboYear.SelectedItem.Value, _
				cboMonth.SelectedItem.Value, _
				Me.SelectedDate.DaysInMonth _
				(cboYear.SelectedItem.Value, _
				cboMonth.SelectedItem.Value))
		End If
		FillDropDownData()
	End Sub

	Private Sub SetLocalizableStrings()
		'If the culture property is empty, use the 
		'value defined for the page.
		If (Me.CultureName = "") Then
			Me.CultureName = Globalization. _
				CultureInfo.CurrentCulture.Name
		End If

		Dim DateResources As New _
			Resources.ResourceManager _
			("DatePicker.DatePickerStrings", _
			System.Reflection.Assembly. _
			GetExecutingAssembly())
		Dim culture As New _
			System.Globalization.CultureInfo _
			(Me.CultureName)

		MonthLabel.Text = DateResources.GetString _
			("MonthLabel", culture)
		DayLabel.Text = DateResources.GetString _
			("DayLabel", culture)
		YearLabel.Text = DateResources.GetString _
			("YearLabel", culture)
	End Sub

End Class
