超酷日历,无弹出式菜单

分享于 

17分钟阅读

Web开发

  繁體

Sample Image - CoolCalendarImg.jpg

介绍

我想感谢微软在. NET 中的运输 Calendar 控制,帮助我们解决许多问题,但它有许多局限性和缺点。 我看到很多文章只是为了改进这个控制。 许多文章建议弹出窗口。 但是我发现很多用户不喜欢弹出窗口。 其次,我们必须编写JavaScript来处理它。 Calendar 控件本身的第二个问题是它不按年份提供导航。 想象一下,当你必须输入 10年后的日期。 即使是 2年,用户也必须点击至少 24次,因此 24的往返行程。 即使是同一年,但 10个月,至少 10个往返行程。 我was这个事实,开始考虑一个更好的解决方案。 最后,我列出了最佳日历的需求。

  • 它应该提供月和年的导航。
  • 它应该提供组合框,以及年份,以选择过去日期。
  • 它不应该显示为弹出菜单。
  • 它应该尽可能地占用窗体上的空间。
  • 它应该自动给控件赋值,不需要编写任何 JavaScript。

在这里,我已经尝试了尽量完成本文中的所有 上面 需求。

希望对你有用。

使用代码

如我所说,不需要再编写一行JavaScript代码。 在工具箱中添加 CoolCalendar 控件的引用。 只需拖动页面上的控件,分配控制( 要向它的分配值的控件,请执行下列操作:) 到 CoolCalander,并享受。

Points of Interest

听起来有趣。"。"。我们开始探索这个控制的魔法 behind。 这是一种复合控制。 它是 Label ( s ),LinkButton ( s ) 和 Calendar 控件的组合。 由于它是复合控件,所以我从 Control 类派生了我的类。 首先,列出我们要记住的要点:

  • 我们需要上月,下个月以及年的导航按钮。
  • 我们需要一个月的下拉框,以及月,但它应该只显示当用户点击月或者年。"。"。
  • 我们需要日历,每天没有 postback 事件。
  • 定义可以引用控件以指定选定日期的属性。
  • 定义属性以指定日期格式。
  • 控件在页面上占用的空间应该更少。

控制核心

由于这是复合控件,所以我们不需要实现/重写 Render 方法。 实际上,控件的主要核心功能是 CreateChildControls。 当控件初始化时,它将在 InitPreRender 事件之前调用这里方法。 我已经在这里创建了所有的子控件。 代码是自解释的。

protectedoverridevoid CreateChildControls() {
 Calendar cal=new Calendar(); 
 //Default Diplay Current Month cal.VisibleDate=DateTime.Today; 
 //disable default heading cal.ShowTitle=false; 
 cal.BackColor=BackColor; 
 cal.ForeColor=ForeColor; 
 cal.Attributes.Add("style","z-index:0"); 
 // By Default control will be render as small text or small Image.// Onclick on this text/image only our calander will be displayedif(ViewState["visibility"]==null) 
 ViewState["visibility"]=false;
 if(Img=="")
 Controls.Add(new 
 LiteralControl(@"<div style='position:absolute;z-index:0' id='"+ 
 this.ID+@":Div1' onClick=""ShowCal('"+this.ID+
 @":Cal')"">Select Date</div><div" + 
 @"style='position:absolute;z-index:0;BACKGROUND-COLOR:"+ 
 HeadingBackColor.Name +";visibility:hidden' id='"+
 this.ID+@":Cal'> <table cellpadding=0" + 
 @"cellspacing=0><tr><td vAlign=""middle"" align=center>"));
 else Controls.Add(new 
 LiteralControl(@"<div style='position:absolute;z-index:0' id='"+ 
 this.ID+@":Div1' onClick=""ShowCal('"+this.ID+ 
 @":Cal')""><img src='"+ Img + 
 "'></img></div><div" + 
 "style='position:absolute;z-index:0;BACKGROUND-COLOR:"+ 
 HeadingBackColor.Name +" ;visibility:hidden' id='"+this.ID+ 
 @":Cal'> <table cellpadding=0" + 
 @"cellspacing=0><tr><td vAlign=""middle"" align=center>"));
 //<div style='position:absolute;left:15px;z-index:0'>Month</div>//<div style='position:absolute;z-index:0'>Year</div> DropDownList cboyear = new DropDownList();
 DropDownList cboMonth= new DropDownList();
 Label lblMonth=new Label();
 Label lblYear=new Label();
 lblMonth.Text = cal.VisibleDate.ToString("MMMM").PadRight(12,' ')+",";
 lblYear.Text=cal.VisibleDate.ToString("yyyy");
 for(int i=2050;i>1049;i--)
 cboyear.Items.Add(i.ToString()); 
 cboMonth.Items.Add("January"); 
 cboMonth.Items.Add("February"); 
 cboMonth.Items.Add("March"); 
 cboMonth.Items.Add("April"); 
 cboMonth.Items.Add("May"); 
 cboMonth.Items.Add("Jun"); 
 cboMonth.Items.Add("July"); 
 cboMonth.Items.Add("Auguest"); 
 cboMonth.Items.Add("September"); 
 cboMonth.Items.Add("October"); 
 cboMonth.Items.Add("November"); 
 cboMonth.Items.Add("December"); 
 cboMonth.AutoPostBack=true; 
 cboyear.AutoPostBack =true; 
 cboMonth.SelectedIndexChanged += new 
 EventHandler(cboMonth_SelectedIndexChanged); 
 cboyear.SelectedIndexChanged += new 
 EventHandler(cboyear_SelectedIndexChanged); 
 LinkButton lblFirst=new LinkButton();
 LinkButton lblPrev=new LinkButton(); 
 LinkButton lblNext=new LinkButton(); 
 LinkButton lblLast=new LinkButton(); 
 lblFirst.Font.Name="Webdings";
 lblPrev.Font.Name="Webdings";
 lblNext.Font.Name="Webdings";
 lblLast.Font.Name="Webdings";
 lblFirst.Attributes.Add("style","TEXT-DECORATION: none;COLOR:"+ 
 HeadingForeColor.Name); 
 lblPrev.Attributes.Add("style","TEXT-DECORATION: none;COLOR:"+ 
 HeadingForeColor.Name); 
 lblNext.Attributes.Add("style","TEXT-DECORATION: none;COLOR:"+ 
 HeadingForeColor.Name); 
 lblLast.Attributes.Add("style","TEXT-DECORATION: none;COLOR:"+ 
 HeadingForeColor.Name); 
 //Tool tips to the Navigation Button lblFirst.Attributes.Add("title","Previous Year"); 
 lblPrev.Attributes.Add("title","Previous Month"); 
 lblNext.Attributes.Add("title","Next Month"); 
 lblLast.Attributes.Add("title","Next Year"); 
 lblPrev.Text="7";
 lblFirst.Text="9";
 lblNext.Text ="8";
 lblLast.Text=":"; 
 lblPrev.Click+=new EventHandler(lblPrev_Click);
 lblFirst.Click+=new EventHandler(lblFirst_Click);
 lblNext.Click+=new EventHandler(lblNext_Click);
 lblLast.Click+=new EventHandler(lblLast_Click);
 lblMonth.Attributes.Add("style","FONT-WEIGHT: bold; COLOR:"+ 
 HeadingForeColor.Name); 
 lblYear.Attributes.Add("style","FONT-WEIGHT: bold; COLOR:"+ 
 HeadingForeColor.Name); 
 Controls.Add(lblFirst); 
 Controls.Add(lblPrev); 
 //Controls.Add(cboMonth);//Controls.Add(cboyear); Controls.Add(lblMonth);
 Controls.Add(lblYear);
 // Hide Month and year dropdown box by defauld will be displayed// when user will click on month or year label. Controls.Add(new LiteralControl(@"<span style='width:"+ 
 200 +"px;background-color:white;position:absolute;left:10px;" + 
 "align:center;visibility:hidden;z-index:0' id='"+ 
 this.ID+ ":Month'>")); 
 Controls.Add(cboMonth);
 Controls.Add(cboyear);
 Controls.Add(new LiteralControl(@"</span>")); 
 Controls.Add(lblNext);
 Controls.Add(lblLast);
 lblMonth.Attributes.Add("OnClick","ShowCal('"+this.ID+@":Month')"); 
 Controls.Add(new LiteralControl("</td></tr><tr><td>"));
 Controls.Add(cal);
 cal.DayRender+=new DayRenderEventHandler(cal_DayRender);
 Controls.Add(new LiteralControl("</td></tr></table></div>"));
}

我们还需要 register 来显示/隐藏用户请求中的Calender 控件。 我们必须在 PreRender 事件上做。 PreRender的代码如下所示:

protectedoverridevoid OnPreRender(EventArgs e)
{
 base.OnPreRender (e);
 if((bool)ViewState["visibility"]==true) 
 {
 if(Img=="")
 ((LiteralControl)Controls[0]).Text= 
 @"<div style='position:absolute;z-index:0' id='"+
 this.ID+@":Div1' onClick=""ShowCal('"+this.ID+
 @":Cal')"">Select Date</div><div style='position:" + 
 @"absolute;z-index:0;BACKGROUND-COLOR:"+HeadingBackColor.Name + 
 ";visibility:visible' id='"+this.ID+@":Cal'> <table" + 
 @"cellpadding=0 cellspacing=0><tr>" + 
 @"<td vAlign=""middle"" align=center>";
 else ((LiteralControl)Controls[0]).Text= 
 @"<div style='position:absolute;z-index:0' id='"+this.ID+ 
 @":Div1' onClick=""ShowCal('"+this.ID+@":Cal')""><img src='"+ 
 Img +"'></img></div><div style='position:" + 
 @"absolute;z-index:0;BACKGROUND-COLOR:"+HeadingBackColor.Name +
 ";visibility:visible' id='"+this.ID+@":Cal'> <table" + 
 @"cellpadding=0 cellspacing=0><tr>" + 
 @"<td vAlign=""middle"" align=center>";
 }
 System.Text.StringBuilder strJavaScript=new System.Text.StringBuilder();
 //Code to emite Javascript that will display Calander. strJavaScript.Append(@"<script language="'JavaScript'">");
 strJavaScript.Append(@"function ShowCal(doc){alert(doc);" + 
 @" document.all[doc].style.visibility='visible';}</script>");
 Page.RegisterClientScriptBlock("CoolCalJavaScript", 
 strJavaScript.ToString()); 
 //Code to emite Javascript that will assign Value to given control strJavaScript.Remove(0,strJavaScript.Length);
 strJavaScript.Append(@"<script language="'JavaScript'">");
 strJavaScript.Append(@"function AssignValue(ctrl,val,doc)" + 
 @"{ document.all[ctrl].value=val;document.all[doc]" + 
 @".style.visibility='hidden';}</script>");
 Page.RegisterClientScriptBlock("CoolCalJavaScript1", 
 strJavaScript.ToString());
}

导航按钮

我们需要四个导航按钮。 到上一年。上个月。下个月和下个月的导航。 我们需要在服务器端捕获 Click 事件,因为我们希望根据按钮点击更改日历的可视日期。

///<SUMMARY>/// To Navigate to Previous Year///</SUMMARY>privatevoid lblPrev_Click(object sender, EventArgs e)
{
 Calendar cal=((Calendar)Controls[12]);
 cal.VisibleDate = cal.VisibleDate.AddMonths(-1);
 ViewState["visibility"]=true; 
 setLabel();
}///<SUMMARY>/// To navigate to preveious Month///</SUMMARY>privatevoid lblFirst_Click(object sender, EventArgs e)
{
 Calendar cal=((Calendar)Controls[12]);
 cal.VisibleDate = cal.VisibleDate.AddYears(-1);
 ViewState["visibility"]=true; 
 setLabel();
}///<SUMMARY>/// To Navigate to Next Month///</SUMMARY>privatevoid lblNext_Click(object sender, EventArgs e)
{
 Calendar cal=((Calendar)Controls[12]);
 cal.VisibleDate = cal.VisibleDate.AddMonths(1);
 ViewState["visibility"]=true; 
 setLabel();
}///<SUMMARY>/// To Navigate to Next Year///</SUMMARY>privatevoid lblLast_Click(object sender, EventArgs e)
{
 Calendar cal=((Calendar)Controls[12]);
 cal.VisibleDate = cal.VisibleDate.AddYears(1);
 ViewState["visibility"]=true; 
 setLabel();
}

同样,我们需要导航到选定月份和选定年份,当月份和年更改时。

/// When Month is changed through Dropdown box///</SUMMARY>privatevoid cboyear_SelectedIndexChanged(object sender, EventArgs e)
{
 Calendar cal=((Calendar)Controls[12]);
 DropDownList cboYear=((DropDownList)Controls[7]);
 cal.VisibleDate =Convert.ToDateTime(cal.VisibleDate.ToString("MM") + 
 "/15/" + cboYear.SelectedItem.Value );
 ViewState["visibility"]=true; 
 setLabel();
}///<SUMMARY>/// When Year is changed through Dropdown box///</SUMMARY>privatevoid cboMonth_SelectedIndexChanged(object sender, EventArgs e)
{
 Calendar cal=((Calendar)Controls[12]);
 DropDownList cboMonth=((DropDownList)Controls[6]);
 cal.VisibleDate =Convert.ToDateTime(cboMonth.SelectedItem.Value + 
 "/15/" + cal.VisibleDate.ToString("yyyy"));
 ViewState["visibility"]=true; 
 setLabel();
}

不带 postback的日历控件

我们不希望我们的日历在用户选择日期时有往返行程。 我们应该使用JavaScript指派选定的日期,我们需要JavaScript代码,以及需要修改日历控件。

Javascript

//Code to emite Javascript that will assign Value to given controlstrJavaScript.Remove(0,strJavaScript.Length);
strJavaScript.Append(@"<script language="'JavaScript'">");
strJavaScript.Append(@"function AssignValue(ctrl,val,doc)" + 
 @"{ document.all[ctrl].value=val;document.all[doc]." + 
 @"style.visibility='hidden';}</script>");
Page.RegisterClientScriptBlock("CoolCalJavaScript1",strJavaScript.ToString());

链接创建

我们必须捕获 DayRender 事件并修改当天的内容。 首先,我们应该删除所有现有控件,然后添加链接,这些链接将在选择时调用 JavaScript。

///<SUMMARY>/// Modify Style of Date Displayed on the Calender to link,/// also remove autopost back to JavaScript///</SUMMARY>privatevoid cal_DayRender(object sender, DayRenderEventArgs e)
{
 // Clear the link from this day e.Cell.Controls.Clear();
 if(!e.Day.IsOtherMonth) 
 {
 // Add the custom link System.Web.UI.HtmlControls.HtmlGenericControl Link = 
 new System.Web.UI.HtmlControls.HtmlGenericControl();
 Link.TagName = "a";
 Link.InnerText = e.Day.DayNumberText;
 Link.Attributes.Add("href","javascript:AssignValue('"+ 
 ControlToAssign +"','"+e.Day.Date.ToString(Format) 
 +"','"+this.ID+@":Cal')");
 Link.Attributes.Add("style","color:white;TEXT-DECORATION: none");
 // Now add our custom link to the page e.Cell.Controls.Add(Link);
 }
 else {
 // Add the custom link System.Web.UI.HtmlControls.HtmlGenericControl Link = 
 new System.Web.UI.HtmlControls.HtmlGenericControl();
 Link.TagName = "a";
 Link.InnerText = e.Day.DayNumberText;
 Link.Attributes.Add("href","#");
 Link.Attributes.Add("style","color:white;TEXT-DECORATION: none");
 }
 if(e.Day.IsToday)
 {
 e.Cell.BackColor = System.Drawing.Color.LightGray;
 }
}

最终触控

我们需要定义 BackgroundColorForeColorHeadingColorHeadingForeColorVisibleDateDateFormatCurrentDateColorImgPath ( 显示初始图像) 和最重要的属性。 由于时间限制,我不能实现全部,但我已经实现了重要的一个。 你可以在本文提交的源代码中得到这个。

历史记录

  • 在 2004年10月10日 上创建。

CAL  POP  日历  弹出  
相关文章