因为项目,需要一个日期输入控件,目前没有看到有特别合适的,所以自己DIY了一个,比较匆忙,说是一瞬间搞定,可也搞了2个小时才搞定的.
   虽然其中使用事件和代码不是很规范,但目前可以凑合能用啦!,放上代码,希望有兴趣的朋友能修改完善一下,也希望大家在此基础上有更好的思路.
   做好以后,具体在页面上效果如下图:

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 成员
    }

}


二.自定义设计时
   为了拖到控件设计器的时候,能大概预览控件外观,所以继承复合控件设计器,使用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();
        }

    }

}


三.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;
     
}

四.使用
   如果是在Visual Studio 2005中编写的,编译以后,引入包含此代码的项目,就可以直接在工具中找到这个控件 "EasyCalender".
直接拖到设计器中就可以使用了,非常方便哦!

^_^
posted on 2007-04-24 18:30  李佩亮  阅读(1540)  评论(3编辑  收藏  举报