網域查詢: www.
返回首頁

一種監听DataList中Calendar事件的解決方法

時間:2010-02-13 00:35來源: 作者: 點擊:
有時你想在DataList的編輯模板項中加入在DataList的模板中加入System.Web.UI.WebControls.Calendar,這樣你可以通過Calendar來更改日期屬性,只需一點,就行了,不需要用戶填寫固定格式的日期.可是在D
  

有時你想在DataList的編輯模板項中加入在DataList的模板中加入System.Web.UI.WebControls.Calendar,這樣你可以通過Calendar來更改日期屬性,只需一點,就行了,不需要用戶填寫固定格式的日期.可是在DataList中System.Web.UI.WebControls.Calendar控件,點擊Calendar,是無法響應SelectDate事件的.它只是進行簡單的提交,不會出發ItemCreated,ItemBound,select,edit,update,cancel等等DataList時間.(可能有,可是俺沒找到)這就是本貼想要解決的問題.
我先前在這個版找了一下,沒看見有人討論這個問題,當然這個如果使用客戶端控件應該可以解決.不過我這個人比較固執,不想用梅花雨,自己做了一個服務器端的控件,來解析DataList中Calendar提交表單的參數(主要就是form["__EVENTARGUMENT"]和form["__EVENTTARGET"]這兩個表單隱藏域),並將結果保存在這個控件中,這樣在稍後就可以訪問到了.

我把解決代碼貼在下面,希望大家多拍磚,多給點意見,我也好有所提高!:)

監听Calendar控件的控件CageCalendar.dll
using System;
using System.Web.UI.WebControls;
using System.Collections.Specialized;

namespace Cage
{
 /// <summary>
 /// CageCalendar用于檢測客戶端Canlendar的SelectedDate事件,通過檢測Form中__EVENTARGUMENT和
 /// __EVENTTARGET的這兩個表單隱藏域,返回相應Canlendar控件中所選擇的日期。本控件主要用于
 /// DataList和DataGrid中的Calendar響應事件的處理,Cage因而得名。
 /// </summary>
 public class CageCalendar : System.Web.UI.Control
 {
  private DateTime dtSniffTime;
  public CageCalendar()
  {
   
  }
  //保存解析的日期,這樣使屬性能夠保存在ViewState中
  public DateTime SniffTime
  {
   get
   {
    return dtSniffTime;
   }
   set
   {
    dtSniffTime = value;
   }
  }

  ///通過相對2000年1月1日的日偏移量,返回相應的時間對象
  ///原理︰檢測表單中得__EVENTARGUMENT和__EVENTTARGET這兩個表單隱藏域,如果合法,將解析後得參數傳給幫助類
  ///返回日期,如果不合法,返回new DateTime()了事
  ///NameValueCollection form︰Web表單的屬性集
  ///string strFindControlPath︰需要進行搜索的DataList控件路徑
  ///string strCalendarName︰需要進行監听的Calendar控件名
  public DateTime GetDateTime(NameValueCollection form,string strFindControlPath,string strCalendarName)
  {
   if(form["__EVENTARGUMENT"] != null &&
    form["__EVENTTARGET"] != null &&
    form["__EVENTARGUMENT"] != "" &&
    form["__EVENTTARGET"] != "" )
   {
    char[] cSplitArray = {':'};
    string[] strPath = form["__EVENTTARGET"].ToString().Split(cSplitArray);
   
    string strTempPath = form["__EVENTTARGET"].Substring(0,form["__EVENTTARGET"].LastIndexOf(":"));
    strTempPath = strTempPath.Substring(0,strTempPath.LastIndexOf(":"));
    string strTempCalendarName = form["__EVENTTARGET"].Substring(form["__EVENTTARGET"].LastIndexOf(":")+1);
    
    if(strTempCalendarName!=strCalendarName)//不是想要找的Calendar控件
     return new DateTime();
    if(strTempPath!=strFindControlPath)//不是想要找的控件路徑
     return new DateTime();

    if(form["__EVENTARGUMENT"].Substring(0,1)!="V")
    {
     return GetDateTime(Convert.ToInt32(form["__EVENTARGUMENT"]));
    }
    else
    {//翻頁
     return new DateTime();
    }
   }

   return new DateTime();
  }

  ///通過相對2000年1月1日的日偏移量,返回相應的時間對象
  ///原理︰根據偏移量計算相應的日期,2000年1月1日的日偏移量為0,往後是正數,往前是負數
  ///天數是每400年為一個周期,這是由閏年造成的
  ///閏年是或被400被整除 或 被4整除但不被100整除的年份
  public DateTime GetDateTime(int iPos)
  {
   int iSign = 1;
   if(iPos < 0)
   {
    iSign = -1;
    iPos = (-1) *iPos;
   }

   int Year4 = (365*4+1);           //一般4年的天數
   int Year400 = Year4*100-3;          //400年的天數,周期
   int[] Year100Array ={Year4*25,Year4*25-1,Year4*25-1,Year4*25-1};//400年中,每100年的天數
   int[] MonthArray = {31,28,31,30,31,30,31,31,30,31,30,31};  //12月中一般的天數
   int[] YearArray = {366,365,365,365};       //4年中一般的天數
   
   int iYearBy400 = iPos/Year400;   //400年的倍數
   int iYearBy400Residue = iPos%Year400; //400年的余數
   int iYearBy100 = 0;      //100年的倍數
   int iYearBy100Residue = 0;    //100年的余數
   int iYearBy4 = 0;      //4年的倍數
   int iYearBy4Residue = 0;    //4年的余數
   int iYearIn4 = 0;      //4年這一小段中所處的年
   int iYearResidue = 0;     //4年這一小段中在所處的年的天的余數
   int iYear=0;       //年
   int iMonth=0;       //月
   int iDay=0;        //日
   int iMonthResidue = 0;     //月中的偏移量
   
   if(iYearBy400Residue == 0)
   {//400整年
    iYear = 2000 + iSign*400*iYearBy400;
    return new DateTime(iYear,1,1);
   }

   int iYear100Start = (Year100Array.Length)*(1-iSign)/2-(1-iSign)/2;
   int iYear100End = (Year100Array.Length)*(1+iSign)/2-(1-iSign)/2;

   iYearBy100Residue = iYearBy400Residue;
   for(int i=iYear100Start; i!=iYear100End;i=i+iSign)
   {//計算在哪個100年內
    iYearBy100Residue = iYearBy100Residue - Year100Array[i];
    if(iYearBy100Residue < 0)
    {
     iYearBy100 = iSign*(i - iYear100Start);
     iYearBy100Residue = iYearBy100Residue + Year100Array[i];
     break;
    }
    else if(iYearBy100Residue == 0)
    {//100整年
     iYearBy100 = iSign*(i - iYear100Start)+1;
     iYear = 2000 + iSign*(400*iYearBy400+100*iYearBy100);
     return new DateTime(iYear,1,1);
    }
   }
   
   if(iSign>0)
   {
    if(iYearBy100==0)
    {
     iYearBy4 = iYearBy100Residue/Year4;    //4年的倍數
     iYearBy4Residue = iYearBy100Residue%Year4;  //4年的余數
    }
    else
    {
     if((iYearBy100Residue-(Year4-1)) == 0)   //被100且不被400整除的不是閏年,應減1
     {
      iYearBy4 = 1;    //4年的倍數
      iYearBy4Residue = 0;  //4年的余數
     }
     else if((iYearBy100Residue-(Year4-1)) < 0)
     {
      iYearBy4 = 0;        //4年的倍數
      iYearBy4Residue = iYearBy100Residue;  //4年的余數
     }
     else
     {
      iYearBy4 = (iYearBy100Residue-(Year4-1))/Year4+1;   //4年的倍數
      iYearBy4Residue = (iYearBy100Residue-(Year4-1))%Year4;  //4年的余數
     }
    }
   }
   else
   {
    iYearBy4 = iYearBy100Residue/Year4;     //4年的倍數
    iYearBy4Residue = iYearBy100Residue%Year4;   //4年的余數
   }

   int iYearStart = (YearArray.Length)*(1-iSign)/2-(1-iSign)/2;
   int iYearEnd = (YearArray.Length)*(1+iSign)/2-(1-iSign)/2;
   int iMonthStart = (MonthArray.Length)*(1-iSign)/2-(1-iSign)/2;
   int iMonthEnd = (MonthArray.Length)*(1+iSign)/2-(1-iSign)/2;
   
   iYearResidue = iYearBy4Residue;
   if(iYearResidue == 0)
   {//4整年
    iYear = 2000 + iSign*(400*iYearBy400 + 100*iYearBy100 + 4*iYearBy4);
    return new DateTime(iYear,1,1);
   }

   for(int i=iYearStart; i!=iYearEnd;i=i+iSign)
   {//計算年
    iYearResidue = iYearResidue - YearArray[i];
    if(iYearResidue <= 0)
    {//找到年的絕對偏移量,相對于2000年!
     iYearIn4 = iSign*(i - iYearStart)+(1-iSign)/2;
     iYearResidue = iYearResidue + YearArray[i];
     //計算月日
     if(i==0)
      MonthArray[2] = MonthArray[2] + 1;//考慮閏月

     iMonthResidue = iYearResidue;
     for(int j=iMonthStart; j!=iMonthEnd; j=j+iSign)
     {
      iMonthResidue = iMonthResidue-MonthArray[j];
      if(iMonthResidue<=0)
      {//找到月!
       iMonth = j+1;
       iDay = iMonthResidue + MonthArray[j];   //偏移量恢復
       iDay = iSign*iDay +(1-iSign)/2*MonthArray[j];//計算日
       break;
      }
     }
  
     iDay = iDay + 1;      //日期是以1開始,而不是零

     if(iDay-MonthArray[iMonth-1] > 0)
     {          //檢測是否超出該月
      iDay = iDay - MonthArray[iMonth-1];

      iMonth++;
      if(iMonth>12)
      {//檢測是否超出該年
       iMonth =1;
       iYearIn4++;
      }
     }

     break;
    }
   }

   iYear = 2000 + iSign*(400*iYearBy400 + 100*iYearBy100 + 4*iYearBy4 + iYearIn4);

   return new DateTime(iYear,iMonth,iDay);
  }

 }
}
在你需要檢測的WebForm中,將這個控件拖進來,並在PageLoad里這麼寫就可以了:
protected Cage.CageCalendar CageCalendar1;
protected System.Web.UI.WebControls.Label Message;
protected System.Web.UI.WebControls.DataList DataList1;
private void Page_Load(object sender, System.EventArgs e)
{
    // 在此處放置用戶代碼以初始化頁面
    if (!IsPostBack)
   {
 bindGrid();
   }
   CageCalendar1.SniffTime = CageCalendar1.GetDateTime(Request.Form,"DataList1","Calendar2");
   if(CageCalendar1.SniffTime != new DateTime())
   {
      string strControlPath =Request.Form["__EVENTTARGET"].Substring(0,Request.Form["__EVENTTARGET"].LastIndexOf(":"))+":TextBox1";
     ((TextBox)Page.FindControl(strControlPath)).Text = CageCalendar1.SniffTime.ToShortDateString();
     ((Calendar)Page.FindControl(Request.Form["__EVENTTARGET"])).VisibleDate = CageCalendar1.SniffTime;
    }
    else
   {
 Test.Text="沒有監听到"+Request.Form["__EVENTTARGET"]+"中的Caledar事件";
   }
}


頂一下
(0)
0%
踩一下
(0)
0%
------分隔線----------------------------
最新評論 查看所有評論
發表評論 查看所有評論
請自覺遵守互聯網相關的政策法規,嚴禁發佈色情、暴力、反動的言論。
評價:
表情:
用戶名: 密碼: 驗證碼:
推薦內容