ASP.NET DateDropDown Control

DateDropDown 是一個使用 UpdatePanel 控制項所建立的連動下拉式日期使用者控制項(User Control)。你可以設定 MinDate 和 MaxDate 屬性,來限制使用者能夠選取的日期範圍,同時也可以搭配驗證控制項檢查使用者輸入的值。

DateDropDown 控制項的完整程式碼如下:
DateDropDown.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="DateDropDown.ascx.cs" 
Inherits="DateDropDown" %>
<asp:UpdatePanel ID="uxUpdatePanel" runat="server">
<ContentTemplate>
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td><asp:DropDownList id="uxYearList" runat="server" AutoPostBack="true"
OnSelectedIndexChanged="uxYearList_SelectedIndexChanged">
</asp:DropDownList></td>
<td>年</td>
<td><asp:DropDownList id="uxMonthList" runat="server" AutoPostBack="true"
OnSelectedIndexChanged="uxMonthList_SelectedIndexChanged">
<asp:ListItem Text="請選擇"></asp:ListItem>
</asp:DropDownList></td>
<td>月</td>
<td><asp:DropDownList id="uxDayList" runat="server">
<asp:ListItem Text="請選擇"></asp:ListItem>
</asp:DropDownList></td>
<td>日</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
<script language="javascript" type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(
function(sender, e) {
var elem = e.get_postBackElement();
if (elem.id == '<%= uxYearList.ClientID %>') {
$get('<%= uxMonthList.ClientID %>').disabled = true;
$get('<%= uxDayList.ClientID %>').disabled = true;
$get('<%= this.ClientID %>').value = '';
}
else if (elem.id == '<%= uxMonthList.ClientID %>') {
$get('<%= uxDayList.ClientID %>').disabled = true;
$get('<%= this.ClientID %>').value = '';
}
});
</script>

DateDropDown.ascx.cs
using System;
using System.Reflection;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

/// <summary>
/// 連動下拉式日期控制項
/// </summary>
[ValidationProperty("Text")]
public partial class DateDropDown : System.Web.UI.UserControl
{
readonly int _maxYear = DateTime.Today.Year + 20;
readonly int _minYear = DateTime.Today.Year - 20;
const string _promptText = "請選擇";

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Initialize();
}

ScriptManager.RegisterHiddenField(uxUpdatePanel, this.ClientID, this.Text);
RegisterScript();
}

private void Initialize()
{
if (Initialized)
return;

Initialized = true;
PopulateYearList();
AssignValidation();
}

private void RegisterScript()
{
string script = string.Format(
@"$get('{0}').onchange = function() {{
$get('{1}').value =
($get('{2}').selectedIndex > 0 && $get('{3}').selectedIndex > 0
&& this.selectedIndex > 0) ?
$get('{2}').value + '-' + $get('{3}').value + '-' + this.value : '';
}};
", uxDayList.ClientID, ClientID, uxYearList.ClientID, uxMonthList.ClientID);

ScriptManager.RegisterStartupScript(Page, Page.GetType(), UniqueID + "_onchange",
script, true);
}

private bool Initialized
{
set
{
ViewState["Initialized"] = value;
}

get
{
if (ViewState["Initialized"] == null)
ViewState["Initialized"] = false;

return (bool)ViewState["Initialized"];
}
}

/// <summary>
/// 取得選取的日期字串
/// </summary>
public string Text
{
get
{
if (uxYearList.SelectedIndex == 0 || uxMonthList.SelectedIndex == 0
|| uxDayList.SelectedIndex == 0)
return string.Empty;

return new DateTime(int.Parse(uxYearList.SelectedValue),
int.Parse(uxMonthList.SelectedValue),
int.Parse(uxDayList.SelectedValue)).ToString("yyyy-MM-dd");
}
}

/// <summary>
/// 取得或設定驗證群組名稱
/// </summary>
public string ValidationGroup
{
get
{
return (string)ViewState["ValidationGroup"];
}
set
{
ViewState["ValidationGroup"] = value;
}
}

/// <summary>
/// 最小日期值
/// </summary>
public DateTime MinDate
{
set
{
ViewState["MinDate"] = value;
}

get
{
if (ViewState["MinDate"] == null)
ViewState["MinDate"] = new DateTime(_minYear, 1, 1);

return (DateTime)ViewState["MinDate"];
}
}

/// <summary>
/// 最大日期值
/// </summary>
public DateTime MaxDate
{
set
{
ViewState["MaxDate"] = value;
}

get
{
if (ViewState["MaxDate"] == null)
ViewState["MaxDate"] = new DateTime(_maxYear, 12, 31);

return (DateTime)ViewState["MaxDate"];
}
}

/// <summary>
/// 取得或設定選取的日期
/// </summary>
public DateTime SelectedDate
{
set
{
if (value < MinDate || value > MaxDate)
throw new ArgumentOutOfRangeException("SelectedDate",
"The value should be between 'MinDate' and 'MaxDate'.");

Initialize();
uxYearList.SelectedValue = value.Year.ToString();
(uxYearList as IPostBackDataHandler).RaisePostDataChangedEvent();
uxMonthList.SelectedValue = value.Month.ToString();
(uxMonthList as IPostBackDataHandler).RaisePostDataChangedEvent();
uxDayList.SelectedValue = value.Day.ToString();
ScriptManager.RegisterExpandoAttribute(uxUpdatePanel,
ClientID, "value", Text, false);
}

get
{
Initialize();

DateTime selectedValue;
if (DateTime.TryParse(Text, out selectedValue))
return selectedValue;

return DateTime.MinValue;
}
}

protected void AssignValidation()
{
foreach (Control control in this.Controls)
{
PropertyInfo property = control.GetType().GetProperty("ValidationGroup");
if (property != null)
{
property.SetValue(control, ValidationGroup, null);
}
}
}

private void PopulateYearList()
{
uxYearList.Items.Clear();
uxYearList.Items.Add(new ListItem(_promptText));

for (int y = MinDate.Year; y <= MaxDate.Year; y++)
{
uxYearList.Items.Add(new ListItem(y.ToString(), y.ToString()));
if (SelectedDate != DateTime.MinValue && y == SelectedDate.Year)
{
uxYearList.Items.FindByValue(y.ToString()).Selected = true;
}
}
}

private void PopulateMonthList(int year)
{
uxMonthList.Items.Clear();
uxMonthList.Items.Add(new ListItem(_promptText));

int minMonth = MinDate.Year == year ? MinDate.Month : 1;
int maxMonth = MaxDate.Year == year ? MaxDate.Month : 12;

for (int m = minMonth; m <= maxMonth; m++)
{
uxMonthList.Items.Add(new ListItem(m.ToString(), m.ToString()));
if (SelectedDate != DateTime.MinValue && m == SelectedDate.Month)
{
uxMonthList.Items.FindByValue(m.ToString()).Selected = true;
}
}

uxMonthList.Enabled = true;
}

private void PopulateDayList(int year, int month)
{
uxDayList.Items.Clear();
uxDayList.Items.Add(new ListItem(_promptText));

int minDay = MinDate.Year == year && MinDate.Month == month ? MinDate.Day : 1;
int maxDay = MaxDate.Year == year && MaxDate.Month == month ?
MaxDate.Day : DateTime.DaysInMonth(year, month);

for (int d = minDay; d <= maxDay; d++)
{
uxDayList.Items.Add(new ListItem(d.ToString(), d.ToString()));
if (SelectedDate != DateTime.MinValue && d == SelectedDate.Day)
{
uxDayList.Items.FindByValue(d.ToString()).Selected = true;
}
}

uxDayList.Enabled = true;
}

protected void uxYearList_SelectedIndexChanged(object sender, EventArgs e)
{
if (uxYearList.SelectedIndex == 0)
{
uxMonthList.SelectedIndex = uxDayList.SelectedIndex = 0;
uxMonthList.Enabled = uxDayList.Enabled = false;
return;
}

PopulateMonthList(int.Parse(uxYearList.SelectedValue));
}

protected void uxMonthList_SelectedIndexChanged(object sender, EventArgs e)
{
if (uxMonthList.SelectedIndex == 0)
{
uxDayList.SelectedIndex = 0;
uxDayList.Enabled = false;
return;
}

PopulateDayList(int.Parse(uxYearList.SelectedValue),
int.Parse(uxMonthList.SelectedValue));
}
}

下列程式碼範例要求使用者輸入一個介於 2009-07-01 到 2010-07-01 之間的日期,並使用 RequiredFieldValidator 來確認控制項的輸入。
<uc1:DateDropDown ID="DateDropDown1" runat="server" ValidationGroup="DateDropDown" 
MinDate="2009-07-01" MaxDate="2010-07-01" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ControlToValidate="DateDropDown1" ValidationGroup="DateDropDown"
ErrorMessage="Please enter a Date!"></asp:RequiredFieldValidator>


Download DateDropDown.zip


Share/Save/Bookmark

0 comments :: ASP.NET DateDropDown Control

張貼留言