close

之前都是利用Calendar控制項提供日曆的畫面及選項:
http://jerry5217.pixnet.net/blog/post/237961279

但如果要針對特定日期加註解或說明,似乎就沒這麼方便了!
行事曆是一週七天反覆循環的表格,所以決定土法煉鋼自己畫一個來用,
像桌曆一樣一次顯示一個月可以換到上或下個月,如下圖:

這個畫面分三個部分,最上面藍色箭頭區域用Label控制項顯示當月份的字樣,
並且在左右二邊用ImageButton控制項執行換到"上"或"下"個月的動作,
節錄程式碼如下:

 

中間綠色箭頭的部分顯示週日~週六的抬頭,字樣不須變化每格寬度固定100px,
這裡用最基本的Html畫表格(Table)的語法就可以了,

最下面紅色箭頭區域依據每七天一週循環的表格方式就是我要利用DataList的地方,
一樣用固定100px寬度,然後再將日期數字放入對應的位置,
前端網頁程式碼如下:

DataList的名稱為DL_BookingCalendar一週七天循環一個Item,
表格中的每一格即代表該月的其中一天,每天設定二個Label控制項,
Label名稱包含Title的控制項,設定用來顯示當天日期的數字,
Label名稱包含Body的控制項,設定用來顯示當天標註說明的內容,
所以一週七天一共會有14個Label控制項。

前端網頁程式碼都設定完成,接下來就是後端如何整理好資料把它塞進去,
使用DataList之前必須先加入System.Data的Namespace

概念是利用System.Data中的DataTable建構完整的資料後,
再將整份表格(Table)資料倒進去(DataBind)給DataList物件,
先說明一下表格的觀念:

以上圖說明,縱向的欄位叫做Column橫向的欄位稱作Row,
Column與Row對應的內容(Cell)就是Data(資料),

※ 建構DataTable的步驟:
1. 建立DataTable物件,並新增Column欄位與定義欄位名稱
    (以上圖表格為例新增Column-1~Column-5總共五個欄位)
2. 在DataTable物件中新增一筆Row,並設定對應Column的資料
3. 重複步驟2.將欄位內容(Cell)中的資料(Data)逐筆設定完成
    (以上圖表格為例步驟2.總共執行五次Row-1~Row-5)
4. 將整份DataTable的資料內容倒(DataBind)給DataList

如果要像桌曆方式呈現完整的一個月,
不可能每個月的第1天都在週日,更不可能最後一天都在週六,
所以一個表格呈現一個月,第一週及最後一週前後都會留空白,
其餘完整一週的7天每一個Cell都會存放資料,

※ 建構一個指定月份表格的步驟:
1. 找出該月第一天是星期幾
2. 找出該月一共有幾天
3. 建立DataTable物件
4. 設定第一週的內容
5. 設定第二週之後不含最後一週的內容
6. 設定最後一週的內容
7. 將DataTable物件內容Binding給DataList

█ 步驟3.即是上述建構DataTable的步驟的1.
█ 步驟4.~6.即是上述建構DataTable的步驟的2.及3.
█ 步驟7.即是上述建構DataTable的步驟的4.

█ 步驟1.要找出指定月份的第一天是星期幾,
只要利用指令DayOfWeek即可:


在這裡回應的內容不是0~6的數字喔!
是"Sunday"、"Monday"、"Tuesday"...星期幾的英文全名,
所以我們可以得到2018年1月的第1天是星期一(Monday),
執行步驟3(第一週內容)時便由此為依據。

█ 步驟2.我們要找指定的那個月份總共有幾天,
也就是最後一天的日期,利用指令DaysInMonth即可取得:


所以我們得到2018年1月的總天數(最後一天的日期)是31,
執行上述步驟5(最後一週內容)時便由此為依據。

首先,
我們先建立一個DataTable並定義與DataList控制項相對應的Column,
意即上述建構DataTable的步驟1.
程式碼節錄如下:

開始逐日將日期數字填入DataTable前,我們先宣告一個變數,
int iM = 0;  這個變數隨時記錄目前處理的日期數字,
該月第一週的內容取決於當月第一天在星期幾,
開始執行上述建構DataTable的步驟2.
如果是星期日(Sunday)該(Row)就從第1格(Cell)開始依序填入日期,

如果是星期一(Monday)則先填1格空白再從第2格開始依序填入日期,

如果是星期二(Tuesday)則先填2格空白再從第3格開始依序填入日期,

..........以此類推,
有注意到嗎?變數iM最後用來存放目前處理到的日期數字,

我們再設定一個變數InquireMonth_First存放當月的首日,
以及設定一個變數InquireMonth_Last存放當月最後一天的日期數字,

剛才指定月份第一週的7種組合方式可利用switch-case指令來執行,

完成了行事曆第一週(第一行Row)的資料後,
在最後一週之前約有三~四行(Row)的資料皆須依日期數字填入,
依據我們設計的DataList,每一行(Row)就是填滿7個欄位(Column),
所以利用變數iM繼續累加及變數InquireMonth_Last來判斷即可達成,

當預先判斷到變數iM+7會大於當月最後一天的日期數字時,
即代表接下來要處理行事曆的最後一行(Row)了,

最後一週與第一週不同,是先填數字後有機會才填空白,
所以依序判斷變數iM的內容是否已到達當月的最後一天,

設定完最後一週的內容後,當月的行事曆表格即大功告成,
此時將建構好的DataTable資料倒給頁面的DataList物件就完成了!

把上述這段程式碼打包成副程式,便可依需求指定要顯示那一個月了!
副程式名稱ReloadCalendar,變數InquireMonth代表需求顯示的月份,
而首頁載入(Page_Load)時就先以當下的日期來呼叫此副程式,

還記得一開始在頁面中設計的行事曆,有選擇上個月或下個月的選項嗎?
把這二個ImageButton控制項的OnClick事件,
設定為執行副程式ReloadCalendar並指定顯示上個月或下個月即可,

█ 指定顯示上個月的ImageButton控制項,OnClick事件:

█ 指定顯示下個月的ImageButton控制項,OnClick事件:

█ 順手再做一個跳回本月的ImageButton控制項,只要指定當下日期即可:

執行網頁或按下右下角重新整理圖示後,頁面顯示當月行事曆:

按下頁面往左的箭頭圖示顯示上個月:

按下頁面往右的箭頭圖示顯示下個月:

下載此段ASP.Net範例的完整程式碼:
(免費開發環境Visual Studio Community 2015~2017)

https://1drv.ms/u/s!Au1CPC3fzWzdgasxl66ot1BOAc-A3Q

 

arrow
arrow

    王振權 發表在 痞客邦 留言(0) 人氣()