因为项目,需要一个日期输入控件,目前没有看到有特别合适的,所以自己DIY了一个,比较匆忙,说是一瞬间搞定,可也搞了2个小时才搞定的.
虽然其中使用事件和代码不是很规范,但目前可以凑合能用啦!,放上代码,希望有兴趣的朋友能修改完善一下,也希望大家在此基础上有更好的思路.
做好以后,具体在页面上效果如下图:
1.控件输出效果
2.点击选择按钮时候的效果
3.可以直接选择月或者年
一.控件代码,继承自CompositeControl类,接口:IPostBackDataHandler(实现数据回调),INamingContainer
二.自定义设计时
为了拖到控件设计器的时候,能大概预览控件外观,所以继承复合控件设计器,使用html 方式描述一个样子出来!代码如下:
三.CSS 样式
因为偷懒的缘故,CSS 我直接保存成文件了,没有按控件方式输出,代码贴出来:
四.使用
如果是在Visual Studio 2005中编写的,编译以后,引入包含此代码的项目,就可以直接在工具中找到这个控件 "EasyCalender".
直接拖到设计器中就可以使用了,非常方便哦!
^_^
虽然其中使用事件和代码不是很规范,但目前可以凑合能用啦!,放上代码,希望有兴趣的朋友能修改完善一下,也希望大家在此基础上有更好的思路.
做好以后,具体在页面上效果如下图:
1.控件输出效果
2.点击选择按钮时候的效果
3.可以直接选择月或者年
一.控件代码,继承自CompositeControl类,接口:IPostBackDataHandler(实现数据回调),INamingContainer
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.Design;
using System.Web.UI.Design.WebControls;
namespace MyControls
{
//描述设计时
[Designer(typeof(EasyCalenderControlDesigners))]
public class EasyCalender : CompositeControl, IPostBackDataHandler, INamingContainer
{
TextBox tb;
System.Web.UI.HtmlControls.HtmlInputButton lb;
RequiredFieldValidator rfv;
RegularExpressionValidator rev;
string _ErrorMsg;
public EasyCalender()
{
//设置默认错误信息
_ErrorMsg = "日期必须输入!";
}
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMsg
{
get { return _ErrorMsg; }
set { _ErrorMsg = value; }
}
/// <summary>
/// 控件选择日期
/// </summary>
public string GetSelectedDate
{
get
{
EnsureChildControls();
if (ViewState[this.ClientID] != null)
return (string)ViewState[this.ClientID];
else
if (tb != null)
return tb.Text;
else
return string.Empty;
}
set
{
EnsureChildControls();
if (tb == null)
tb = new TextBox();
tb.Text = value;
}
}
/// <summary>
/// 是否启用必须输入验证控件
/// </summary>
public bool EnableRequiredFieldValidator
{
get
{
EnsureChildControls();
if (rfv == null)
{
rfv = new RequiredFieldValidator();
}
return rfv.Enabled;
}
set
{
EnsureChildControls();
if (rfv == null)
{
rfv = new RequiredFieldValidator();
}
rfv.Enabled = value;
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//注册脚本
RegisterJavaScript();
//初始化输入控件
if (tb == null)
tb = new TextBox();
if (ViewState[this.ClientID] != null)
tb.Text = ViewState[this.ClientID].ToString();
this.Controls.Add(tb);
//初始化Html button 选择按钮
lb = new System.Web.UI.HtmlControls.HtmlInputButton("button");
lb.Value = "选择";
lb.Attributes.Add("onclick", "showCalender(this,'" + tb.ClientID + "')");
this.Controls.Add(lb);
//初始化必须输入控件
if (rfv == null)
rfv = new RequiredFieldValidator();
rfv.ControlToValidate = tb.ID;
rfv.ErrorMessage = _ErrorMsg;
if (rfv.Enabled)
this.Controls.Add(new LiteralControl("<font color='red'>*</font>"));
this.Controls.Add(rfv);
//初始化日期格式验证控件
if (rev == null)
rev = new RegularExpressionValidator();
rev.ControlToValidate = tb.ID;
rev.ErrorMessage = "请按日期格式输入!";
rev.ToolTip = "请按格式输入!";
rev.ValidationExpression = @"^(\d{4})-((1[0-2])|(0?[1-9]))-((3[0-1])|([1-2][0-9])|(0?[1-9]))$";
this.Controls.Add(rev);
}
/// <summary>
/// 注册JavaScript 脚本
/// </summary>
private void RegisterJavaScript()
{
string ScriptString = @"
<script type=""text/javascript"">
var allMonth=[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var allNameOfWeekDays=[""一"",""二"", ""三"", ""四"", ""五"", ""六"", ""七""];
var allNameOfMonths=[""一月"",""二月"",""三月"",""四月"",""五月"",""六月"",""七月"",""八月"",""九月"",""十月"",""十一月"",""十二月""];
var newDate=new Date();
var yearZero=newDate.getFullYear();
var monthZero=newDate.getMonth();
var day=newDate.getDate();
var currentDay=0, currentDayZero=0;
var month=monthZero, year=yearZero;
var yearMin=2000, yearMax=2010;
var target='';
var hoverEle=false;
function setTarget(e){
if(e) return e.target;
if(event) return event.srcElement;
}
function newElement(type, attrs, content, toNode) {
var ele=document.createElement(type);
if(attrs) {
for(var i=0; i<attrs.length; i++) {
eval('ele.'+attrs[i][0]+(attrs[i][2] ? '=\u0027' :'=')+attrs[i][1]+(attrs[i][2] ? '\u0027' :''));
}
}
if(content) ele.appendChild(document.createTextNode(content));
if(toNode) toNode.appendChild(ele);
return ele;
}
function setMonth(ele){month=parseInt(ele.value);calender()}
function setYear(ele){year=parseInt(ele.value);calender()}
function setValue(ele) {
if(ele.parentNode.className=='week' && ele.firstChild){
var dayOut=ele.firstChild.nodeValue;
if(dayOut < 10) dayOut='0'+dayOut;
var monthOut=month+1;
if(monthOut < 10) monthOut='0'+monthOut;
//target.value=dayOut+'.'+monthOut+'.'+year;
target.value=year+'-'+monthOut+'-'+dayOut;
removeCalender();
}
}
function removeCalender() {
var parentEle=document.getElementById(""calender"");
while(parentEle.firstChild) parentEle.removeChild(parentEle.firstChild);
document.getElementById('basis').parentNode.removeChild(document.getElementById('basis'));
}
function calender() {
var parentEle=document.getElementById(""calender"");
parentEle.onmouseover=function(e) {
var ele=setTarget(e);
if(ele.parentNode.className=='week' && ele.firstChild && ele!=hoverEle) {
if(hoverEle) hoverEle.className=hoverEle.className.replace(/hoverEle ?/,'');
hoverEle=ele;
ele.className='hoverEle '+ele.className;
} else {
if(hoverEle) {
hoverEle.className=hoverEle.className.replace(/hoverEle ?/,'');
hoverEle=false;
}
}
}
while(parentEle.firstChild) parentEle.removeChild(parentEle.firstChild);
function check(){
if(year%4==0&&(year%100!=0||year%400==0))allMonth[1]=29;
else allMonth[1]=28;
}
function addClass (name) { if(!currentClass){currentClass=name} else {currentClass+=' '+name} };
if(month < 0){month+=12; year-=1}
if(month > 11){month-=12; year+=1}
if(year==yearMax-1) yearMax+=1;
if(year==yearMin) yearMin-=1;
check();
var control=newElement('p',[['id','control',1]],false,parentEle);
var controlPlus=newElement('a', [['href','javascript:month--;calender()',1],['className','controlPlus',1]], '<', control);
var select=newElement('select', [['onchange',function(){setMonth(this)}]], false, control);
for(var i=0; i<allNameOfMonths.length; i++) newElement('option', [['value',i,1]], allNameOfMonths[i], select);
select.selectedIndex=month;
select=newElement('select', [['onchange',function(){setYear(this)}]], false, control);
for(var i=yearMin; i<yearMax; i++) newElement('option', [['value',i,1]], i, select);
select.selectedIndex=year-yearMin;
controlPlus=newElement('a', [['href','javascript:month++;calender()',1],['className','controlPlus',1]], '>', control);
check();
currentDay=1-new Date(year,month,1).getDay();
if(currentDay > 0) currentDay-=7;
currentDayZero=currentDay;
var newMonth=newElement('table',[['cellSpacing',0,1],['onclick',function(e){setValue(setTarget(e))}]], false, parentEle);
var newMonthBody=newElement('tbody', false, false, newMonth);
var tr=newElement('tr', [['className','head',1]], false, newMonthBody);
tr=newElement('tr', [['className','weekdays',1]], false, newMonthBody);
for(i=0;i<7;i++) td=newElement('td', false, allNameOfWeekDays[i], tr);
tr=newElement('tr', [['className','week',1]], false, newMonthBody);
for(i=0; i<allMonth[month]-currentDayZero; i++){
var currentClass=false;
currentDay++;
if(currentDay==day && month==monthZero && year==yearZero) addClass ('today');
if(currentDay <= 0 ) {
if(currentDayZero!=-7) td=newElement('td', false, false, tr);
}
else {
if((currentDay-currentDayZero)%7==0) addClass ('holiday');
td=newElement('td', (!currentClass ? false : [['className',currentClass,1]] ), currentDay, tr);
if((currentDay-currentDayZero)%7==0) tr=newElement('tr', [['className','week',1]], false, newMonthBody);
}
if(i==allMonth[month]-currentDayZero-1){
i++;
while(i%7!=0){i++;td=newElement('td', false, false, tr)};
}
}
}
function showCalender(ele,tbele) {
if(document.getElementById('basis')) { removeCalender() }
else {
//target=document.getElementById(ele.id.replace(/for_/,''));
target=document.getElementById(tbele);
var basis=ele.parentNode.insertBefore(document.createElement('div'),ele);
basis.id='basis';
newElement('div', [['id','calender',1]], false, basis);
calender();
}
}
</script>
";
//注册到页面
ClientScriptManager csManager = this.Page.ClientScript;
csManager.RegisterClientScriptBlock(this.Page.GetType(), this.ClientID, ScriptString);
}
IPostBackDataHandler 成员
}
}
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.Design;
using System.Web.UI.Design.WebControls;
namespace MyControls
{
//描述设计时
[Designer(typeof(EasyCalenderControlDesigners))]
public class EasyCalender : CompositeControl, IPostBackDataHandler, INamingContainer
{
TextBox tb;
System.Web.UI.HtmlControls.HtmlInputButton lb;
RequiredFieldValidator rfv;
RegularExpressionValidator rev;
string _ErrorMsg;
public EasyCalender()
{
//设置默认错误信息
_ErrorMsg = "日期必须输入!";
}
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMsg
{
get { return _ErrorMsg; }
set { _ErrorMsg = value; }
}
/// <summary>
/// 控件选择日期
/// </summary>
public string GetSelectedDate
{
get
{
EnsureChildControls();
if (ViewState[this.ClientID] != null)
return (string)ViewState[this.ClientID];
else
if (tb != null)
return tb.Text;
else
return string.Empty;
}
set
{
EnsureChildControls();
if (tb == null)
tb = new TextBox();
tb.Text = value;
}
}
/// <summary>
/// 是否启用必须输入验证控件
/// </summary>
public bool EnableRequiredFieldValidator
{
get
{
EnsureChildControls();
if (rfv == null)
{
rfv = new RequiredFieldValidator();
}
return rfv.Enabled;
}
set
{
EnsureChildControls();
if (rfv == null)
{
rfv = new RequiredFieldValidator();
}
rfv.Enabled = value;
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//注册脚本
RegisterJavaScript();
//初始化输入控件
if (tb == null)
tb = new TextBox();
if (ViewState[this.ClientID] != null)
tb.Text = ViewState[this.ClientID].ToString();
this.Controls.Add(tb);
//初始化Html button 选择按钮
lb = new System.Web.UI.HtmlControls.HtmlInputButton("button");
lb.Value = "选择";
lb.Attributes.Add("onclick", "showCalender(this,'" + tb.ClientID + "')");
this.Controls.Add(lb);
//初始化必须输入控件
if (rfv == null)
rfv = new RequiredFieldValidator();
rfv.ControlToValidate = tb.ID;
rfv.ErrorMessage = _ErrorMsg;
if (rfv.Enabled)
this.Controls.Add(new LiteralControl("<font color='red'>*</font>"));
this.Controls.Add(rfv);
//初始化日期格式验证控件
if (rev == null)
rev = new RegularExpressionValidator();
rev.ControlToValidate = tb.ID;
rev.ErrorMessage = "请按日期格式输入!";
rev.ToolTip = "请按格式输入!";
rev.ValidationExpression = @"^(\d{4})-((1[0-2])|(0?[1-9]))-((3[0-1])|([1-2][0-9])|(0?[1-9]))$";
this.Controls.Add(rev);
}
/// <summary>
/// 注册JavaScript 脚本
/// </summary>
private void RegisterJavaScript()
{
string ScriptString = @"
<script type=""text/javascript"">
var allMonth=[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var allNameOfWeekDays=[""一"",""二"", ""三"", ""四"", ""五"", ""六"", ""七""];
var allNameOfMonths=[""一月"",""二月"",""三月"",""四月"",""五月"",""六月"",""七月"",""八月"",""九月"",""十月"",""十一月"",""十二月""];
var newDate=new Date();
var yearZero=newDate.getFullYear();
var monthZero=newDate.getMonth();
var day=newDate.getDate();
var currentDay=0, currentDayZero=0;
var month=monthZero, year=yearZero;
var yearMin=2000, yearMax=2010;
var target='';
var hoverEle=false;
function setTarget(e){
if(e) return e.target;
if(event) return event.srcElement;
}
function newElement(type, attrs, content, toNode) {
var ele=document.createElement(type);
if(attrs) {
for(var i=0; i<attrs.length; i++) {
eval('ele.'+attrs[i][0]+(attrs[i][2] ? '=\u0027' :'=')+attrs[i][1]+(attrs[i][2] ? '\u0027' :''));
}
}
if(content) ele.appendChild(document.createTextNode(content));
if(toNode) toNode.appendChild(ele);
return ele;
}
function setMonth(ele){month=parseInt(ele.value);calender()}
function setYear(ele){year=parseInt(ele.value);calender()}
function setValue(ele) {
if(ele.parentNode.className=='week' && ele.firstChild){
var dayOut=ele.firstChild.nodeValue;
if(dayOut < 10) dayOut='0'+dayOut;
var monthOut=month+1;
if(monthOut < 10) monthOut='0'+monthOut;
//target.value=dayOut+'.'+monthOut+'.'+year;
target.value=year+'-'+monthOut+'-'+dayOut;
removeCalender();
}
}
function removeCalender() {
var parentEle=document.getElementById(""calender"");
while(parentEle.firstChild) parentEle.removeChild(parentEle.firstChild);
document.getElementById('basis').parentNode.removeChild(document.getElementById('basis'));
}
function calender() {
var parentEle=document.getElementById(""calender"");
parentEle.onmouseover=function(e) {
var ele=setTarget(e);
if(ele.parentNode.className=='week' && ele.firstChild && ele!=hoverEle) {
if(hoverEle) hoverEle.className=hoverEle.className.replace(/hoverEle ?/,'');
hoverEle=ele;
ele.className='hoverEle '+ele.className;
} else {
if(hoverEle) {
hoverEle.className=hoverEle.className.replace(/hoverEle ?/,'');
hoverEle=false;
}
}
}
while(parentEle.firstChild) parentEle.removeChild(parentEle.firstChild);
function check(){
if(year%4==0&&(year%100!=0||year%400==0))allMonth[1]=29;
else allMonth[1]=28;
}
function addClass (name) { if(!currentClass){currentClass=name} else {currentClass+=' '+name} };
if(month < 0){month+=12; year-=1}
if(month > 11){month-=12; year+=1}
if(year==yearMax-1) yearMax+=1;
if(year==yearMin) yearMin-=1;
check();
var control=newElement('p',[['id','control',1]],false,parentEle);
var controlPlus=newElement('a', [['href','javascript:month--;calender()',1],['className','controlPlus',1]], '<', control);
var select=newElement('select', [['onchange',function(){setMonth(this)}]], false, control);
for(var i=0; i<allNameOfMonths.length; i++) newElement('option', [['value',i,1]], allNameOfMonths[i], select);
select.selectedIndex=month;
select=newElement('select', [['onchange',function(){setYear(this)}]], false, control);
for(var i=yearMin; i<yearMax; i++) newElement('option', [['value',i,1]], i, select);
select.selectedIndex=year-yearMin;
controlPlus=newElement('a', [['href','javascript:month++;calender()',1],['className','controlPlus',1]], '>', control);
check();
currentDay=1-new Date(year,month,1).getDay();
if(currentDay > 0) currentDay-=7;
currentDayZero=currentDay;
var newMonth=newElement('table',[['cellSpacing',0,1],['onclick',function(e){setValue(setTarget(e))}]], false, parentEle);
var newMonthBody=newElement('tbody', false, false, newMonth);
var tr=newElement('tr', [['className','head',1]], false, newMonthBody);
tr=newElement('tr', [['className','weekdays',1]], false, newMonthBody);
for(i=0;i<7;i++) td=newElement('td', false, allNameOfWeekDays[i], tr);
tr=newElement('tr', [['className','week',1]], false, newMonthBody);
for(i=0; i<allMonth[month]-currentDayZero; i++){
var currentClass=false;
currentDay++;
if(currentDay==day && month==monthZero && year==yearZero) addClass ('today');
if(currentDay <= 0 ) {
if(currentDayZero!=-7) td=newElement('td', false, false, tr);
}
else {
if((currentDay-currentDayZero)%7==0) addClass ('holiday');
td=newElement('td', (!currentClass ? false : [['className',currentClass,1]] ), currentDay, tr);
if((currentDay-currentDayZero)%7==0) tr=newElement('tr', [['className','week',1]], false, newMonthBody);
}
if(i==allMonth[month]-currentDayZero-1){
i++;
while(i%7!=0){i++;td=newElement('td', false, false, tr)};
}
}
}
function showCalender(ele,tbele) {
if(document.getElementById('basis')) { removeCalender() }
else {
//target=document.getElementById(ele.id.replace(/for_/,''));
target=document.getElementById(tbele);
var basis=ele.parentNode.insertBefore(document.createElement('div'),ele);
basis.id='basis';
newElement('div', [['id','calender',1]], false, basis);
calender();
}
}
</script>
";
//注册到页面
ClientScriptManager csManager = this.Page.ClientScript;
csManager.RegisterClientScriptBlock(this.Page.GetType(), this.ClientID, ScriptString);
}
IPostBackDataHandler 成员
}
}
二.自定义设计时
为了拖到控件设计器的时候,能大概预览控件外观,所以继承复合控件设计器,使用html 方式描述一个样子出来!代码如下:
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.Design.WebControls;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace MyVoiceWeb.EasyCalender
{
/// <summary>
/// 简单日期控件设计时
/// </summary>
public class EasyCalenderControlDesigners : CompositeControlDesigner
{
public override string GetDesignTimeHtml()
{
return "<input type='input' value=''><input type='button' value='选择'>";
//return base.GetDesignTimeHtml();
}
}
}
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.Design.WebControls;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace MyVoiceWeb.EasyCalender
{
/// <summary>
/// 简单日期控件设计时
/// </summary>
public class EasyCalenderControlDesigners : CompositeControlDesigner
{
public override string GetDesignTimeHtml()
{
return "<input type='input' value=''><input type='button' value='选择'>";
//return base.GetDesignTimeHtml();
}
}
}
三.CSS 样式
因为偷懒的缘故,CSS 我直接保存成文件了,没有按控件方式输出,代码贴出来:
#basis {
display:inline;
position:relative;
}
#calender {
position:absolute;
top:30px;
left:0;
width:220px;
background-color:#fff;
border:3px solid #ccc;
padding:10px;
z-index:10;
}
#control {
text-align:center;
margin:0 0 5px 0;
}
#control select {
font-family:""Lucida sans unicode"", sans-serif;
font-size:11px;
margin:0 5px;
vertical-align:middle;
}
#calender .controlPlus {
padding:0 5px;
text-decoration:none;
color:#333;
}
#calender table {
empty-cells: show;
width:100%;
font-size:11px;
table-layout:fixed;
}
#calender .weekdays td{
text-align:right;
padding:1px 5px 1px 1px;
color:#333;
}
#calender .week td {
text-align:right;
cursor:pointer;
border:1px solid #fff;
padding:1px 4px 1px 0;
}
#calender .week .today {
background-color:#ccf;
border-color:#ccf;
}
#calender .week .holiday {
font-weight: bold;
}
#calender .week .hoverEle {
border-color:#666;
background-color:#99f;
color:#000;
}
display:inline;
position:relative;
}
#calender {
position:absolute;
top:30px;
left:0;
width:220px;
background-color:#fff;
border:3px solid #ccc;
padding:10px;
z-index:10;
}
#control {
text-align:center;
margin:0 0 5px 0;
}
#control select {
font-family:""Lucida sans unicode"", sans-serif;
font-size:11px;
margin:0 5px;
vertical-align:middle;
}
#calender .controlPlus {
padding:0 5px;
text-decoration:none;
color:#333;
}
#calender table {
empty-cells: show;
width:100%;
font-size:11px;
table-layout:fixed;
}
#calender .weekdays td{
text-align:right;
padding:1px 5px 1px 1px;
color:#333;
}
#calender .week td {
text-align:right;
cursor:pointer;
border:1px solid #fff;
padding:1px 4px 1px 0;
}
#calender .week .today {
background-color:#ccf;
border-color:#ccf;
}
#calender .week .holiday {
font-weight: bold;
}
#calender .week .hoverEle {
border-color:#666;
background-color:#99f;
color:#000;
}
四.使用
如果是在Visual Studio 2005中编写的,编译以后,引入包含此代码的项目,就可以直接在工具中找到这个控件 "EasyCalender".
直接拖到设计器中就可以使用了,非常方便哦!
^_^