65.9K
CodeProject 正在变化。 阅读更多。
Home

日期选择器用户控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.66/5 (40投票s)

2007 年 12 月 7 日

CPOL

6分钟阅读

viewsIcon

396940

downloadIcon

18276

ASP.NET 中的日期选择器用户控件(C#, VS2010)

引言

这是一个简单的日期选择器控件,它是一个 ASP.NET 自定义控件。用户可以输入日期到文本框中,或者点击一个图标弹出一个日历。JavaScript 用于显示弹出日历。通过引用该程序集并将控件从工具箱拖放到 Web 窗体上,可以轻松地将该控件集成到您自己的 ASP.NET 网站中。

背景

此控件最初基于另一个 CodeProject 文章。在我 2007 年的第一个版本发布时,我对该控件进行了重构,使其可以在 VS2005 中编译,并且可以在最新版本的 Firefox 和 Internet Explorer 中工作。我修复了一些 JavaScript 错误,并增加了更好的设计时支持和数据绑定。在第一个版本中,日期选择器控件是一个所谓的“用户控件”(.ascx 文件),您需要将其与一些 JavaScript、CSS 和图像文件一起包含在 ASP.NET Web 项目中。

现在,在 2011 年,我发布了一个新的主要版本。这次,日期选择器被实现为一个自定义控件。这意味着它是一个程序集(DLL 文件),您可以简单地从您的 ASP.NET Web 应用程序中引用它,然后从工具箱将其拖放到 Web 窗体上。所有必需的资源,如 JavaScript、CSS 或图像文件,都包含在单个 DLL 中,并作为 Web 资源加载。

Using the Code

要在您自己的 Web 项目中使用日期选择器控件,只需添加对DatePickerControl.dll的引用,该文件可以从本页面顶部的链接下载。

要手动将日期选择器实例添加到.aspx窗体,请添加以下代码

<%@ Register assembly="DatePickerControl" 
namespace="DatePickerControl" tagprefix="cc1" %>

<cc1:DatePicker ID="DatePicker1" runat="server" />

如果您想在工具箱中拥有datepicker控件,您需要手动添加它。为此,右键单击工具箱,然后从上下文菜单中选择“选择项...”。然后单击“浏览...”按钮并选择DatePickerControl.dll。您的工具箱中会出现一个新控件,您可以将其拖放到任何 Web 窗体上

我学到的东西

在开发这个自定义控件的过程中,我学到了很多关于自定义控件开发的知识。有几点我想分享。

Web 资源

我的控件使用了额外的资源,如图像、CSS 和 JavaScript 文件。因为我想将所有内容都包含在一个 DLL 中,所以我将所有必需的文件添加为“嵌入的资源”。请确保所有资源文件的“生成操作”属性设置为“嵌入的资源”。然后,您需要编辑“AssemblyInfo.cs”文件,并为每个您希望通过自动生成的 URL 访问的文件添加一个“WebResource”声明。

[assembly: System.Web.UI.WebResource("DatePickerControl.Resources.popcalendar.css", 
	"text/css")]
[assembly: System.Web.UI.WebResource("DatePickerControl.Resources.popcalendar.js", 
	"text/javascript", PerformSubstitution = true)]
[assembly: System.Web.UI.WebResource("DatePickerControl.Resources.calendar.gif", 
	"image/gif")]    

要获取其中一个资源文件的 URL,请使用“Page.ClientScript.GetWebResourceUrl”方法。例如,要包含 JavaScript 文件,我使用以下代码

 Page.ClientScript.RegisterClientScriptInclude(this.GetType(), "js",
    Page.ClientScript.GetWebResourceUrl(this.GetType(), 
	"DatePickerControl.Resources.popcalendar.js"));    

向传递给“Page.ClientScript.GetWebResourceUrl”方法的string添加程序集名称非常重要!

顺便说一下:由“Page.ClientScript.GetWebResourceUrl”方法返回的 URL 看起来大致是这样的

 /WebResource.axd?d=VKJPowiRQrngH4t6...wQza83c1&t=634583660937215237    

属性默认值

我还想要一些设计时支持,例如我的控件的属性应该有一个默认值。并且我希望默认值在属性网格中显示为默认(=非粗体),而非默认值显示为非默认(=粗体)。

对于StringIntEnum属性,这相当容易,可以通过在属性声明中添加一些额外的属性来实现。

[Category("Appearance")]
[Description("Day to start week with.")]
[Browsable(true)]
[DefaultValue(Weekday.Monday)]
public Weekday StartWeekWithDay
{

但是对于DateFormat属性,我希望默认值是与区域性相关的:在欧洲 Windows 安装上,默认日期格式应该是 dd.MM.yyyy,而在美国系统上,默认值应该是 MM/dd/yyyy。这该如何实现呢?幸运的是,我们也可以编写自己的代码来设置属性的默认值。为此,我们必须为属性添加两个private方法。这些方法必须命名为Reset...()ShouldSerialize...(),其中...被替换为属性的名称。让我们看看DateFormat属性。

public string DateFormat
{
    get { return dateFormat; }
    set { dateFormat = value; }
}

private void ResetDateFormat()
{
    DateFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
}

private bool ShouldSerializeDateFormat()
{
    return (!DateFormat.Equals
	(CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern));
}

ResetDateFormat()方法只是将属性设置为您应该的默认值。ShouldSerializeDateFormat()方法返回一个布尔值,用于确定属性值是否需要被序列化。只有当它与默认值不同时才需要。

HTML 设计时

在设计器中,日期选择器控件的显示方式与实际网页上的显示方式大不相同。不幸的是,我无法找到一种方法在设计时显示嵌入资源中的日历图像。

然而,我了解到,您可以通过向您的控件 DLL 添加一个继承自“ControlDesigner”的类来控制用于在设计时渲染控件的 HTML。该类必须与控件同名,但后缀为“Designer”。对于“DatePicker”控件,此类将命名为“DatePickerDesigner”。在此类中,可以重写“GetDesignTimeHtml()”方法以返回自定义 HTMLstring

CSS 和 JavaScript 包含

当您将日期选择器控件放置到 Web 窗体上时,它应该会自动包含所需的 CSS 和 JavaScript 文件。但是,如果您在同一页面上放置两个或多个日期选择器控件,这些文件应该只包含一次。要包含 JavaScript 文件,可以使用“RegisterClientScriptInclude”方法。

Page.ClientScript.RegisterClientScriptInclude
	(this.GetType(), "js", "your_javascript.js");

即使该方法被多个控件实例多次调用,此方法也能自动确保相同的 JavaScript 只被包含一次。

包含 CSS 文件会更复杂一些。正如我们所知,CSS 文件应该包含在 Web 页面的<head></head>标签内。页面标题中的控件可以通过“Page.Header”属性访问。可以使用以下代码添加指向 CSS 文件的链接。

LiteralControl include = new LiteralControl
    ("<link href='your_css.css' rel='stylesheet' type='text/css' />");
Page.Header.Controls.Add(include);  

但是,如果我们向同一页面添加了多个日期选择器控件,我们如何确保相同的 CSS 只包含一次呢?我们可以利用前面提到的“RegisterClientScriptInclude”方法。还有一个名为“Page.ClientScript.IsClientScriptIncludeRegistered”的方法,我们可以用它来查询 JavaScript 是否已经被包含。因此,我们可以在 JavaScript 尚未包含的情况下包含 CSS。

历史

  • 2007 年 12 月 -- 发布了原始版本
  • 2009 年 4 月 -- 更新(大量错误修复,迁移到 VS2008,添加了示例)
  • 2010 年 8 月 -- 更新了源代码和演示
  • 2011 年 12 月 -- 重写为自定义控件,所有内容编译到一个 DLL 中,迁移到 VS2010,添加了更多示例
© . All rights reserved.