ASP.NET - Date Picker 服务器控件
本文提供了一个开发 ASP.NET Date Picker 服务器/用户控件的示例。它包括源代码和可直接使用的构建版本(二进制)。

引言
本文提供了一个开发 ASP.NET Date Picker 服务器控件的示例,其中利用了:嵌入式 Web 资源、客户端脚本、内部属性和国际化(日期格式化)。它包括源代码和可直接使用的构建/演示版本。
背景
我花了一段时间在网上寻找免费的开源日期选择器控件,但找不到完全满足我需求的。由于我以前没有机会制作自己的服务器控件,我想我应该创建一个日期选择器控件并分享我的经验。
本次发布有两个主要重点。首先,由于我是澳大利亚人(d/MM/yyyy),我希望该控件能够通过国际化支持不同的文化日期格式。其次,该控件需要通过利用内部属性持久化模式来提供高度的样式/外观控制。
Using the Code
DatePicker
服务器控件是一个输入控件,允许用户从日历中选择日期。默认情况下,控件的Culture
属性设置为CultureInfo.CurrentCulture
,它使用 Web 应用程序/服务器的当前区域性。但是,通过将Culture
属性的值更改为新的CultureInfo
,DatePicker
控件也可以使用不同的区域性。DatePicker
控件中显示的选定日期文本将按照Culture
属性指定的格式显示。
DatePicker
控件包含几个属性,允许您控制控件的外观。可以使用标记或代码隐藏将样式应用于日历窗格的不同元素。DatePicker
控件的显示宽度(以单位计)由其Width
属性确定。由于在 Internet Explorer 中遇到一个问题,控件的宽度由文本框的宽度设置。
您还可以通过更改FirstDayOfWeek
属性的值来指定日历周的第一天。默认情况下,一周的第一天设置为星期日。通过设置TodaysDate
属性的值,也可以更改代表今天的日期。同样,您可以设置DateSelected
属性。
DatePicker
控件允许在更改选定日期时进行自动回发。这可以通过更改AutoPostBack
属性的值来设置。
DatePicker 成员
公共属性
AlternateMonthStyle
:获取或设置上个月和下个月日期单元格的样式。AutoPostBack
:获取或设置控件在选定日期更改时是否回发。默认值为False
。CalendarTableStyle
:获取或设置内部日历表的样式。PaneWidth
:获取或设置浮动窗格的宽度。默认为 150px。Culture
:获取或设置控件的区域性。默认为CultureInfo.CurrentCulture
。DayHeaderStyle
:获取或设置日历日期标题行的样式。FirstDayOfWeek
:获取或设置日历的周第一天。MonthStyle
:获取或设置当前月份位置的日期单元格样式。NextPrevMonthStyle
:获取或设置上/下个月导航链接的样式。NextPrevYearStyle
:获取或设置上/下一年导航链接的样式。PaneHeaderStyle
:获取或设置窗格标题的样式。PaneTableStyle
:获取或设置窗格的样式。可用于更改窗格的边框样式。SelectedDate
:获取或设置控件的选定日期。SelectedStyle
:获取或设置选定日期单元格的样式。TitleStyle
:获取或设置月份日历标题的样式。TodaysDate
:获取或设置代表今天的日期的日期。TodayStyle
:获取或设置今天的日期单元格的样式。
公共事件
SelectedDateChanged
:在选定日期成功更改时发生。如果日期无法解析,将抛出错误。
关注点
嵌入 Web 资源
要访问存储在服务器控件程序集内的图像和 JavaScript 等嵌入式资源,您可以使用WebResource特性。在创建资源文件或更改文件的生成操作(到“嵌入式资源”)后,您可以将WebResource
程序集引用插入到类的命名空间中。
[assembly: WebResource("SlimeeLibrary.Images.DatePicker.gif","image/gif")]
[assembly: WebResource("SlimeeLibrary.Javascript.DatePicker.js", "text/javascript")]
[assembly: WebResource("SlimeeLibrary.Javascript.DateTime.js", "text/javascript")]
namespace SlimeeLibrary
{
}
注册客户端脚本
结合使用嵌入式 Web 资源进行客户端 JavaScript,您可以使用Page.ClientScript属性来检查控件的嵌入式 Web 资源是否已注册,并注册任何新的 JavaScript。
以下示例检查脚本是否已注册。如果未注册,它将注册该脚本。
if (!Page.ClientScript.IsClientScriptIncludeRegistered(this.GetType(), "DatePicker"))
{
Page.ClientScript.RegisterClientScriptInclude("DatePicker",
Page.ClientScript.GetWebResourceUrl(this.GetType(),
"SlimeeLibrary.Javascript.DatePicker.js"));
}
持久化模式内部属性
要允许在 ASP.NET 标记中定义样式,您可以使用PersistenceModeAttribute.Mode特性属性。定义类属性的持久化模式将启用此功能。
[Category("Appearance"),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TableStyle PaneTableStyle
{
get
{
if (_paneTableStyle == null)
{
// Set Default Style
_paneTableStyle = new TableStyle();
_paneTableStyle.BorderStyle = BorderStyle.Solid;
_paneTableStyle.BorderColor = System.Drawing.ColorTranslator.FromHtml("gray");
_paneTableStyle.BorderWidth = new Unit("1px");
}
return _paneTableStyle;
}
set { PaneTableStyle.CopyFrom(value); }
}
以下 ASP.NET 标记演示了内部属性功能。
<cc1:DatePicker ID="DatePicker1" runat="server" AutoPostBack="true"
Width="100px" PaneWidth="150px">
<PaneTableStyle BorderColor="#707070" BorderWidth="1px" BorderStyle="Solid" />
<PaneHeaderStyle BackColor="#0099FF" />
<TitleStyle ForeColor="White" Font-Bold="true" />
<NextPrevMonthStyle ForeColor="White" Font-Bold="true" />
<NextPrevYearStyle ForeColor="#E0E0E0" Font-Bold="true" />
<DayHeaderStyle BackColor="#E8E8E8" />
<TodayStyle BackColor="#FFFFCC" ForeColor="#000000"
Font-Underline="false" BorderColor="#FFCC99"/>
<AlternateMonthStyle BackColor="#F0F0F0"
ForeColor="#707070" Font-Underline="false"/>
<MonthStyle BackColor="" ForeColor="#000000" Font-Underline="false"/>
</cc1:DatePicker>
国际化 - 控制日期格式
通过引用System.Globalization
命名空间并利用CultureInfo.DateTimeFormat属性,您可以确定所需的日期格式,并根据设置的区域性解析选定的日期。
[Category("Behaviour"),
Description("Set the culture for parsing the date values.")]
public CultureInfo Culture
{
get
{
object o = ViewState["Culture"];
return (o != null) ? (CultureInfo)o : CultureInfo.CurrentCulture;
}
set { ViewState["Culture"] = value; }
}
// Monitor selected value change. Raise SelectedDateChanged event on change.
protected virtual void OnSelectedDateChanged(object sender, EventArgs e)
{
//If date can't be parsed throw format exception.
//For other exceptions throw system exception.
if (textBox.Text != string.Empty)
{
try
{
this.SelectedDate = DateTime.Parse(textBox.Text, Culture);
if (SelectedDateChanged != null)
{
SelectedDateChanged(this, e);
}
}
catch (FormatException ex)
{
throw new FormatException("Invalid selected date format.
Could not parse date.", ex);
}
catch (Exception ex)
{
throw new Exception("Unknown exception.", ex);
}
}
}
历史
随着控件的更新,我将在此区域进行版本控制。如果您有任何想法或建议,请随时告知我。请关注我的博客,我计划很快创建更多控件。我也在寻找一些可以贡献的在线项目。如果您有需要帮助的项目,请告诉我。非常感谢。
v1.0.2 - 小更新
2009年10月13日:修复了加载时SelectedDate
属性的问题
v1.0.1 - 小更新
2009年10月12日:修复了控件在内容占位符内时呈现的 ID 问题