之前都是利用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

 

相关文章