一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

WM有約(三):下一次是什么時候?

Written by Allen Lee

 

不要留戀過去

怎樣才能約束用戶,不讓其選擇過去的日期呢?有一個很傻的辦法,就是每次啟動應(yīng)用程序的時候,自動把MonthCalendar控件的MinDate屬性的值設(shè)為今天。這樣雖然禁止了用戶選擇過去的日期,卻帶來另外一些問題:

  • 當(dāng)月之前的日期無法查看。
  • 和選項窗體的Min Date設(shè)置相沖。

有鑒于此,我們采用另一種辦法,就是在用戶選中某個日期時,判斷這個日期是否已經(jīng)過去,若是,則禁用Pin菜單項,若否,則啟用Pin菜單項。那么,如何獲知用戶選中了某個日期?最簡單的辦法就是使用MonthCalendar控件的DateChanged事件:

代碼 1

運(yùn)行應(yīng)用程序,你會發(fā)現(xiàn),當(dāng)我選中今天或者將來的日期時,Pin菜單項是啟用的(圖1),而當(dāng)我選中過去的日期時,Pin菜單項則是禁用的(圖2):

圖 1

圖 2

 

這(幾)天不要選

在繼續(xù)之前,我們有必要搞清楚,"排除某(幾)天"究竟是什么意思。在這里,"排除某(幾)天"并不是指禁止用戶選中那(幾)天,而是指那(幾)天不在計劃中,但我們很清楚,計劃趕不上變化,或許那(幾)天真正到來的時候又可以選了。

和之前的"釘住日期"相比,"排除日期"除了無需在MonthCalendar控件上有所反映之外,其它部分基本上是一樣的,它支持排除某天、連續(xù)的幾天和某個周末,用來保存被排除的日期的文件和應(yīng)用程序放在同一個文件夾里,應(yīng)用程序在啟動的時候會檢查這個文件是否存在,如果不存在就創(chuàng)建一個空白的文件。從上面這些描述來看,"排除日期"和"釘住日期"在很大程度上共享著相同的代碼,于是,接下來就是考慮如何重用現(xiàn)有的代碼并實現(xiàn)新的功能。

首先要處理的是LoadPinnedDates和SavePinnedDates兩個方法(參見《WM有約(一):你好,CF》的代碼5和代碼6),我們提取這兩個方法的代碼,并創(chuàng)建兩個新的方法:

代碼 2

代碼 3

這樣,LoadPinnedDates和SavePinnedDates兩個方法就可以簡化為分別對LoadDates和SaveDates兩個方法的調(diào)用了,而LoadExcludedDates和SaveExcludedDates兩個方法也可以如法炮制了。在著手實現(xiàn)這些方法之前,我們還需要提供一個東西,那就是文件的路徑,也是我們接下來需要做的事情——改造GetFilePath方法(參見《WM有約(一):你好,CF》的代碼4),改造后的GetFilePath方法將會用來映射文件路徑:

代碼 4

有了這些準(zhǔn)備,我們就可以著手實現(xiàn)LoadExcludedDates和SaveExcludedDates兩個方法了:

代碼 5

至于LoadPinnedDates和SavePinnedDates兩個方法的新版本就留給讀者自行處理了。

接著就是"排除日期"的核心功能——ExcludeWeekend和ExcludeRange兩個方法了,它們與PinWeekend和PinRange兩個方法(參見《WM有約(一):你好,CF》的代碼1和代碼2)的最大區(qū)別就是不需要把操作結(jié)果反映在MonthCalendar控件上,而它們的共同之處是都要計算具體的日期并把它們添加到對應(yīng)的集合里。我們先來看看計算具體的日期這部分功能,它分為兩種情況,一種是計算周末的,另一種是計算兩個日期之間的,如果這兩個日期相同,則視為一天,于是,我們可以創(chuàng)建CalculateWeekend和CalculateRange兩個方法來分別負(fù)責(zé)這兩種情況:

代碼 6

有了這些準(zhǔn)備,我們就可以著手實現(xiàn)ExcludeWeekend和ExcludeRange兩個方法了:

代碼 7

至于PinWeekend和PinRange兩個方法的新版本就留給讀者自行處理了。

還差什么呢?對,用戶界面,沒有這個,我們辛苦了這么久就白干了:

圖 3

還有Exclude菜單項的相關(guān)代碼:

代碼 8

噢,別忘了在InitializeFile方法(參見《WM有約(一):你好,CF》的代碼12)里添加檢查文件是否存在的代碼,以及在適當(dāng)?shù)牡胤教砑颖4鏀?shù)據(jù)的代碼,否則……

運(yùn)行應(yīng)用程序,選中2009年1月17日到2009年1月31日之間的日期,然后單擊Exclude菜單項:

圖 4

通過資源管理器找到ExcludedDates.txt文件,然后用Word Mobile查看里面的內(nèi)容,結(jié)果發(fā)現(xiàn)只有下面3天!

圖 5

問題出在哪里?原來,我選中的那幾天的開始日期恰好是星期六,于是應(yīng)用程序"自作聰明"地把它視為一般周末!如何解決這個問題?回到代碼8,我們知道,ExcludeWeekend方法的調(diào)用需要滿足兩個條件,第一個是用戶只選中了一天,另一個則是這天是星期六。要知道用戶是否只選中了一天,我們只需要看看SelectionStart和SelectionEnd兩個屬性是否同一天:

代碼 9

再次運(yùn)行應(yīng)用程序,這次就正常了:

圖 6

需要提醒的是,Pin菜單項的相關(guān)代碼由于應(yīng)用了相同的邏輯,于是也存在相同的問題,不過解決方法是一樣的,所以這里就不說了。另外,因為"排除日期"不像"釘住日期"那樣會在用戶界面上有所反映,所以當(dāng)我們單擊Exclude菜單項時,一切都在后臺完成,如果用戶不知情的話,感覺起來就像什么也沒干一樣,為了增強(qiáng)用戶體驗,最好就顯示一個消息框告訴用戶日期已被排除。

 

這(幾)天應(yīng)該選

由于"包含日期"和"排除日期"極其相似,再加上我們在實現(xiàn)"排除日期"時提取的公共代碼也適用于"包含日期",于是,我們可以用非一般的速度來實現(xiàn)"包含日期"的內(nèi)部邏輯:

代碼 10

至于用戶界面,我們同樣為它添加一個Include菜單項:

圖 7

而這個菜單項的相關(guān)代碼如下:

代碼 11

其它東西,例如應(yīng)用程序啟動的時候檢查用來保存日期的文件是否存在、讀取保存的日期和在適當(dāng)?shù)臅r候保存日期,和前面的實現(xiàn)大同小異,這里就不細(xì)說了。

運(yùn)行應(yīng)用程序,選中2009年2月14日,然后單擊Include菜單項:

圖 8

由于這天剛好是星期六,所以應(yīng)用程序執(zhí)行了包含周末的邏輯,這也是預(yù)期的行為:

圖 9

到了這里,你可能會認(rèn)為"排除日期"和"包含日期"也是時候告一段落了,但事實上我們還有一個問題需要處理。試想一下,如果我對同一個日期先后執(zhí)行包含和排除操作,那么應(yīng)用程序是否應(yīng)該分別在m_IncludedDates和m_ExcludedDates兩個集合里登記這個日期?我們知道,"排除日期"和"包含日期"都是用來反映計劃的調(diào)整,比起分別在兩個地方登記同一個日期,執(zhí)行抵消操作或許更有意義。舉個例子,剛才我包含了2009年2月14日,現(xiàn)在我要排除這個日期,那么應(yīng)用程序應(yīng)該從m_IncludedDates里刪除這個日期而不是向m_ExcludedDates添加這個日期。怎么樣?是不是很簡單?然而,這個東西實現(xiàn)起來一點(diǎn)都不容易,因為我們通常操作的是一組日期而不是單個日期,如果我們足夠好運(yùn),那么要抵消的日期集合會是被抵消的日期集合的子集,如果我們不夠運(yùn)氣,那么……一般地,如果我們要包含一組日期,那么我們要先檢查m_ExcludedDates是否包含了這些日期的部分或全部,如果是,則從m_ExcludedDates里刪除相同部分,剩下的才添加到m_IncludedDates。以IncludeWeekend方法(參見代碼10)為例,從最初的monthCalendar1.SelectionStart到最后的m_IncludedDates.AddRange需要經(jīng)過如下四步:

圖 10

其中,第三步的Subtract方法是解決這個問題的關(guān)鍵,那么,如何實現(xiàn)這個方法呢?我們知道,List本身沒有提供這個方法,要想達(dá)到這樣的效果就得使用C# 3.0的擴(kuò)展方法了。下面來看看我的實現(xiàn):

代碼 12

對于second里的每個日期,Subtract方法試圖從first里刪除,并通過Remove方法的返回值判斷刪除操作是否成功,如果不成功,就意味著這個日期應(yīng)該添加到m_IncludedDates里,于是返回這個日期。有了這些準(zhǔn)備,我們就可以著手修改IncludeWeekend方法:

代碼 13

另外,IncludeRange、ExcludeWeekend和ExcludeRange等方法也需要修改,不過都是大同小異,所以就不一一列舉了。

 

下一次是什么時候?

下一次……在MonthCalendar控件下面……

圖 11

通常,這種可預(yù)測的"下一次"都意味著計算周期的存在,對于這個應(yīng)用程序,這個周期是兩周,以星期六為計算基準(zhǔn),比如說,假設(shè)上圖的5、6和7三天已被釘住,那么 下次應(yīng)該被釘住的日期將會是19、20和21三天,于是"Next time:"下面的Label就應(yīng)該顯示"2008年12月19日"。這個計算過程的一般形式如下圖所示:

圖 12

有了這些分析,我們就可以著手實現(xiàn)CalculateNextTime方法了:

代碼 14

故事到此結(jié)束了嗎?當(dāng)然不是,前面我們花了這么多精力來實現(xiàn)"排除日期"和"包含日期",如果僅僅用來保存一些日期,那么我也未免太無聊了。

首先,我們來看看"包含日期"將會如何影響"下一次"的計算,還是借用圖11,假設(shè)19、20和21三天已被釘住,今天是23號,那么"Next time:"下面的Label應(yīng)該顯示"2009年1月2日",但如果26、27和28三天已被包含,那么"Next time:"下面的Label就應(yīng)該顯示"2008年12月26日"了。簡而言之,在時間軸上排在前面的"包含日期"將會取代使用默認(rèn)算法計算出來的日期:

代碼 15

接著,我們再來看看"排除日期"將會如何影響"下一次"的計算,假設(shè)2、3和4三天已被釘住,今天是6號,那么"Next time:"下面的Label應(yīng)該顯示"2009年1月17日",但如果17到31之間的日期已被排除,那么"Next time:"下面的Label就應(yīng)該顯示"2009年2月7日"了。

圖 13

簡而言之,"排除日期"會導(dǎo)致使用默認(rèn)算法計算出來的日期逐周往后推,直到計算出來的日期沒被排除為止:

代碼 16

由此可見,完整的CalculateNextTime方法應(yīng)該包含如下四步:

圖 14

其中,第一步和第四步是從代碼14里分解出來的:

代碼 17

有了這些準(zhǔn)備,我們就可以著手實現(xiàn)完整的CalculateNextTime方法了:

代碼 18

最后,終于到最后了,我們要把計算結(jié)果顯示在應(yīng)用程序主窗體的"Next time:"下面,那么,我們應(yīng)該在什么時候顯示呢,又應(yīng)該在什么時候更新呢?用Activated事件!你可能會問,為什么不用Load事件呢?這是因為當(dāng)用戶單擊應(yīng)用程序右上角的關(guān)閉按鈕時,應(yīng)用程序?qū)嶋H上只是最小化到后臺,當(dāng)用戶通過菜單或者其它方式再次啟動應(yīng)用程序時,實際上只是把應(yīng)用程序"還原"到前臺,而在這個過程里L(fēng)oad事件并不會被觸發(fā)。事不宜遲,讓我們完成本集的最后一段代碼吧:

代碼 19

運(yùn)行應(yīng)用程序,終于看到下一次是什么時候了:

圖 15

 

你還想要什么?

在這本集里,我們花費(fèi)巨大精力實現(xiàn)"下一次"的計算,然而,"除了'現(xiàn)在',你永遠(yuǎn)不能生活在任何其他時刻,你所能得到的只是現(xiàn)在的時光,未來在到來時也只不過是另一個現(xiàn)在"([美]韋恩·W·戴爾,《你的誤區(qū)》),好好把握每一個"現(xiàn)在",你將會得到一個滿意的軌跡。

到目前為止,應(yīng)用程序的用戶界面都是為"垂直"屏幕設(shè)計的,有沒有想過,假如用戶旋轉(zhuǎn)設(shè)備的屏幕,使之變成"水平"的,將會發(fā)生什么事情呢?下一集,我們將會探討這個問題及其解決方案,我們還會嘗試創(chuàng)建用戶控件來封裝MonthCalendar控件、"下一次"Label以及相關(guān)的代碼,如果"時間"允許的話,我們還會看看如何在這個用戶控件上實現(xiàn)數(shù)據(jù)綁定。

相關(guān)文章:

WM有約(一):你好,CF

WM有約(二):配置信息

 

NET技術(shù)WM有約(三):下一次是什么時候?,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 一级美女毛片 | 欧美激情国产一区在线不卡 | 久久精品国产福利 | 欧亚激情偷乱人伦小说视频 | 欧美亚洲国产精品久久 | 美女胸又www又黄网站 | 成年美女黄的视频网站 | 六月婷婷久香在线视频 | 国产日韩精品欧美在线ccc | 国产大片91精品免费看3 | 久久国产精品99久久久久久老狼 | 天天色天天干天天射 | 奇米亚洲春色 | 精品视频在线观看一区二区三区 | 午夜在线免费视频 | 怡红院日韩 | 天堂网色 | 国产一区二区在线视频播放 | 久热国产在线视频 | 秒播在线 | 韩国一级做a爰片性色毛片 韩国一区二区三区 | 性欧美激情在线观看 | 久久在精品线影院精品国产 | 伊人久久精品 | 亚洲国产中文字幕在线观看 | 国产每日更新 | 中文字幕在线视频观看 | 好爽毛片一区二区三区四区 | 亚洲精品永久www嫩草 | 好吊妞在线播放 | 天天天色综合 | 久久精品国产亚洲a不卡 | 欧美在线不卡视频 | 思思久久99热这里只有精品66 | 怡红院在线观看精品 | 99综合色| 四虎永久地址4hu紧急入口 | 四虎国产精品永久地址99新强 | 污片网站在线看 | 色综合精品久久久久久久 | 久久精品这里热有精品2015 |