2011年12月28日 星期三

應無所住,而生其心


張老師357期的月刊裡,剛好有一篇是林烱垚蘇一仲(和泰興業董事長)的精彩訪談對話,牽引出《金剛經》裡「應無所住,而生其心」這一句。「 無所住 」是什麼呢?就是不在一個念頭或任何現象上產生執著,牢牢不放。比如受了打擊,被心外的事物所困擾,那叫心有所住。當身在紅塵能不受紅塵困擾,更可進一步出入紅塵且能救濟紅塵中的眾生,為他們說法。這個心就是慈悲心和智慧心,是佛和菩薩們的境界。這就是「生其心」。(Ref 3)


林烱垚(以下簡稱林):先請問您關於電視上引人側目,「爭第二」廣告的原始構想?
蘇一仲(以下簡稱蘇):喔,It is a little bit long story.很多年前,我在美國的時候,曾經看到艾維斯汽車租賃公司的一個廣告詞:「We are the second, we will try hard.」帶給我滿深的印象。
後來,回到台灣,等我開始代理「大金」時,要先做形象上的「定位」,討論很久,最後用「日本一番」做定位。而當開始寫廣告故事時,用什麼東西來代表日本第一,又是一個要思考的問題。我們想過富士山、東京鐵塔、劍術、柔道……等,最後終於想到了sumo(相撲),而相撲的最高位階是「橫綱」,講的是「心、技、體」,也就是內外兼修,很符合我們對公司的期許,所以就用相撲來support廣告故事;至於其中一支拍攝小徒弟問師父,外頭吵鬧聲是在爭什麼?師父回答「他們在爭第二」的廣告構想,就是來自於當年艾維斯租車的廣告詞。只是沒想到,「爭第二」的臺詞後來竟然經常被引用。


講求親身體驗,掌握改變的時機
:這樣的理念,您是不是也同樣用在公司的經營,或是對員工的期許上?
:對,像我在公司就立下了「210」的目標,「2」指的是兩百億日幣,「10」是指西元2010年,也就是期許公司能在2010年達到兩百億日幣的營業額,能夠真正不只是「Nippon一級棒」,也是「台灣一級棒」。另外,我們也朝突破與創新發展;所以,當大家在賣窗型冷氣機時,我們只賣分離式冷氣機;當別人賣一對一時,我們賣一對多;而別牌都在賣定頻時,我們賣的是變頻;人家賣單機,我們就賣系統機……。

:看起來,您一直都在求變?
:我有一句廣告詞是「要最好,你非變不可」,是用在變頻冷氣機上,但也是有其他意義的。像《易經》說:「窮則變,變則通,通則久」,我常在想,「久」了之後,是不是又會循環成「窮」呢?那麼,是不是應該要「未窮先變」,防患於未然呢?又好比《心經》講:「色即是空,空即是色」,所謂的「空」,並不是「沒有」,而是指「會變化」,也就是「無常」。這也讓我想到,在企業管理上大家都會談到「P、D、C、A」:plan(計畫)、do(演練)、check(檢查)、act(執行),而每個月我們會看一次資產負債表,可是看到這些資料時都是過去式了,真有問題,也只能「窮則變」;那麼,為什麼不能「未窮先變」呢?所以,我把PDCA改成dynamic PDCA(動態的PDCA),也就是所謂的「走動管理」,並且提出「三現主義」:到「現地」、看「現物」、掌握「現情」;就是一切都講求親身體驗,掌握改變的時機。


有時候還是應該放下主觀、虛心就教
:那麼,對於變,您是以什麼做為準則?
:我的最高思考、行為規範是《金剛經》寫的:「應無所住,而生其心」。也就是不要執著,能夠順應情勢做調整。一般人都會有「習慣領域」,其實反而會因為「習慣」而受到限制。我來講個故事:有一個阿嬤和孫子住在一起,阿嬤住在樓下,孫子住樓上;老人家晚上都比較早睡,而年輕的孫子則是玩到三更半夜才回家。他每次回到家,腳一踢,一隻鞋子「咚」一聲掉到地上,把阿嬤給驚醒了;再踢一下,又「咚」一聲,另一隻鞋子也掉到地上。所以,每天阿嬤都要聽到這兩聲巨響後,才能再度入睡。於是,阿嬤就跟孫子說:「憨孫,阿嬤老了要早睏,你卡暗轉來沒關係,可是你脫鞋子卡細聲點。」之後幾個禮拜都相安無事。有一天,孫子回到家,忘了阿嬤的叮嚀,一聲「咚」,鞋子丟到地上,這時,他突然想起阿嬤的話,趕緊輕聲把另一隻鞋子脫了。隔天,阿嬤埋怨他說:「憨孫,你昨瞑為啥只有『咚』一聲,就無第二聲,害我為了等第二聲,整晚都無睏。」
另一個故事是,有一次英國伊莉沙白女王的船艦行經英吉利海峽時,突然一陣大霧,航行視線變得十分模糊。這時,突然傳來燈號:「希望船艦往左十五度。」艦長不理會。沒多久,又一個燈號:「拜託往左十五度。」艦長依舊不理會,因為在他的習慣中,這是皇家艦隊,只有別人讓開,怎可能自己讓對方的。最後,一個燈號:「你要直直開也沒關係,不過,我這裡是燈塔。」

我們以往的各種經驗在腦子裡屯積,慢慢成為一種固定的思考、行為模式,這就是習慣領域,它成為了我們的意識形態,卻往往也局限、困住了我們。所以,有時候還是應該放下主觀、虛心就教,也就是「應無所住」;然後「而生其心」,智慧才能產生。

「把事情徹底做好」,這就是心態
:很精采、有趣的故事和道理。人生的確有很多的變,那麼,您會建議年輕朋友,該以什麼樣的心態面對改變中所遇到的挫折?
:人生不如意十之八九,應該要有「山不轉路轉,路不轉人轉,人不轉心轉」的心態,也就是要能「轉念」,這樣看事情就會有不一樣的心情。所以,當我們碰到問題的時候,要先能勇敢去「面對它」;然後是「接受它」,這一點很難,因為人一遇到問題,很習慣會怪東怪西,把責任都推到別人身上,而「接受它」就是要能放下傲慢心,重新檢討;等心平氣和,才能產生智慧,這時才能「處理它」;而當你盡了最大的努力後,結果不一定會照著自己的期待走,那時就必須能「放下它」,因為日子還是要過下去。這就是聖嚴法師所說的「四它」。

:很深的智慧;不過,我想,年輕人可能第一關就過不了。
:年輕人血氣方剛,遇到問題,多少很難去面對,這是常理。不過,這也讓我想到,最近有很多學生延遲畢業,因為耽心畢業即是失業,或是就必須面對工作職場的挑戰。不過,我還是覺得,社會也是個大學,可以提供很多學習管道,所以還是應該早點面對社會的歷練。另外,我認為,不喜歡念書也沒關係,能學習一技之長,同樣也可以成就大事業,像王永慶、比爾蓋茲,都是很不錯的典範。

談到就業,人生有四業:就業、職業、事業、志業,是經驗、年紀累積的不同呈現,也是心態上的差異。有個人看到三個水泥工在工作,他問第一個水泥工:「你在做什麼?」他回答說:「我在堆磚」;第二個水泥工說:「我在砌一道牆」;第三個則說:「我在蓋一座教堂」。這也就是「態度決定高度」;所以,心態很重要。國父說:「人生要立志做大事,不要立志做大官」,聽起來像陳腔濫調,可是仔細推敲,他所謂的「做大事」,應該就是指「把事情徹底做好」,這就是心態。
所以,年輕人在組織裡面不要怕沒有機會,只要努力做、認真學,並且問自己,當機會來到時,「Are you ready?」

除了「四勿」,更要「四多」
:最後,談談您的收藏,看到您辦公室裡有許多猴子雕像,對您是不是有特殊的意義?
:有一次我到日本旅遊,在東照寺看到寺廟屋頂上有幾隻擺出不同動作的猴子雕像,讓我想起孔子的「四勿」說,覺得很有意思,就開始收集起來。後來,除了道德版(非禮勿言、非禮勿聽、非禮勿視、非禮勿動),日本還推出了現代版,強調的是「四多」:多看、多聽、多說、多做。更積極、有趣,我也收集到了。而我參加扶輪社後,社員必須遵守四大考驗:我們所想的、所說、所做的事應先捫心自問:一、是否一切屬於真實?二、是否各方得到公平?三、是否促進信譽友誼?四、能否兼顧彼此利益?於是,我就融合猴子的動作和四大考驗,設計出「真實」、「公平」、「友誼」、「互惠」四款大金相撲寶寶的造型,也用來期許全體同仁。

:看來您把許多理念都融入行銷和管理上,並且「身體力行」,令人敬佩。謝謝您精采的言論和經驗分享!


參考:

2011年12月27日 星期二

使用 jQuery 清除畫面輸入的資料

自己在查詢頁面撰寫「清除」按鈕的 jQuery 程式,發現還是整理起來,日後還蠻有機會參考的。

Case 1:將 ASP.Net 的 DropDownList 跳到預設選項。

假設下拉選單 ddl_DeptList1 預設第一個選項的值是空字串,則可以用
$("select[id*=ddl_DeptList1]").val("");


Case 2:將 ASP.Net 的 DropDownList 內容清除。
假設下拉選單 ddl_DeptList2 已經有許多 option 資料,則可以用
 $("select[id*=ddl_DeptList2]").find("option").remove();


Case 3:將 ASP.Net 的 CheckBox 勾選取消。
假設核選方塊 cbStatus 已經有許多勾選資料,則可以用
$("input[name*=cbStatus]").each(function () { this.checked = false; });


Case 4:將 ASP.Net 的 Radio Button 勾選取消。
假設挑選方塊 rb_cust_type 已經有一筆挑選資料,則可以用
$("input[name*=rb_cust_type]").each(function () { this.checked = false; });


Case 5:將 ASP.Net 的 TextBox 內容清除。
假設輸入方塊 tbx_date_start 已經有使用者輸入的資料,則可以使用
$("input[id*=tbx_date_start]").val("");




2011年12月23日 星期五

非專業影音剪輯

不管你是要辦尾牙,還是要給朋友驚喜,免不了要有些配樂或是影片。但我們的預算跟時間,通常不是不足,就是沒有。在這種情況下,如果有一些可依循的剪輯範例參考,一定可以加快完成的腳步。以下是自己這次參與活動時,找到的相關的製作方法,分享給有需要的人。另外,有些方法是使用線上服務,這意謂著很有可能在不久的將來,就會停止提供。

case 1:將 youtube 的影片,轉成 mp3 。
透過 http://2conv.com/,在 youtube 搜尋影片,並將聲音檔轉存成 mp3
更多轉 mp3 的資訊:http://blog.yam.com/michaelwu30/article/19630671 (痞子DJ)


case 2:裁剪 mp3 。
透過下載免費的 Eusing Free MP3 Cutter


假設共有三個檔案(1.mp3, 2.mp3, 3.mp3,將其合併為一個檔案 final.mp3)
(1)開始 → 執行
(2)打 cmd ,按 Enter 進入命令視窗
(3) copy /b 1.mp3 + 2.mp3 + 3.mp3 final.mp3

 PS: /b 指定一個二位元檔案   /a 指定一個 ASCII 檔案
可參考 DOS 指令大全


case 4:將 youtube 的影片,轉成 mp4。
透過 http://kej.tw/flvretriever/

步驟一:把 Youtube 的網址內容複製到下面的位置,並點選按鈕「RETRIVE NOW!」



步驟二:把「下載此檔案」的連結內容另存新檔,並用記事本開啟後,把內容複製,並貼到下圖的框框裡,再按「送出」按鈕。


步驟三:最後會得到許多下面的超連結,您可以根據可供下載的清單,挑選您想要使用的格式,並按右鍵另存新檔即可。





此外,如果上述方法失效,也可以參考另一個方法:http://www.makeuseof.com/tag/4-quick-ways-to-download-youtube-videos-off-the-net/

case 5:編排影片(剪輯、串接不同影片、加特效)。
使用 win7 的 Windows Live Movie Maker


到此,可能你會發現,除了作業系統 win7 是要花錢購買之外,基本上這些軟體都是免費的。

case 6:最近學到抓 Youtube 檔案最輕鬆的方法。
隨著時日的進步,竟然已經有人提供一個不用大腦只需刪除3個字就可以直接下載影片或音檔的方式。

首先,先從 Youtube 找到您要的影片,假如網址是:
https://www.youtube.com/watch?v=kZd4_oziflw

那你只要記得將 youtube 的後三碼去掉,變成 yout
完整網址變成
https://www.yout.com/watch?v=kZd4_oziflw

將這網址貼到瀏覽器上,就可以跑出下面的結果:


您就可以選擇「MP3」或「MP4」的下載類型了。


詳細說明請參考:去掉網址裡的三個字母就能下載Youtube影片

2011年12月13日 星期二

千金之子,不死於市


在史記《貨殖列傳》裡,記載了一句成語:「千金之子,不死於市。」自己不僅有點陌生,更遑論成語背後所代表的故事了。好奇心的驅使下,意外的對於這個令後人感嘆的故事,在心中升起無限漣漪。

詳細的故事介紹,可以參閱【TG】的「范蠡的小故事」一文。

看完後的心得,個人對於范蠡能夠斷然地捨棄權勢與財富,其操守與德行已非一般人所及。在他當陶朱公時,一方面不斷地在商界上展現出過人的智慧,另一方面也更勤奮地在積聚財富。但金錢在他眼裡到底佔了什麼份量,我想,用「視如土芥」這句話,對他來說,算是一種稱讚吧。真正能夠讓他有興趣的,是如何把肚子裡頭的學問,在現實生活中實踐出來,隨之而來的金錢與權勢,只稱得上是「附加價值」。

舉例來說,在范蠡的經商事蹟中,不斷出現「人棄我取,人取我予」最高指導原則,換句白話來說,就是「低買高賣」。然而人心通常隨大盤起伏,真正能貫徹執行的人真的不多啊。但范蠡真的就做到了,甚至將這理念擴展應用到糧食、漁業、生絲、鹽場...等等。在【註一】裡,節錄了《越對吳的作戰指導原則》,裡面論述一段在危險與機會中取得平衡的,就是要「客觀」,也透漏出范蠡不僅僅是個學識淵博的人,更在心性的修為上,有著很深的功夫。


在這麼一位富爸爸的教養下,三個兒子是否真有盡得父親真傳?在「千金之子,不死於市」的故事中,很明顯看得出來各個兒子的差別。但在此之前,據《史記•越王勾踐世家》所言:「朱公居陶,生少子。」,可以推估老三的生長背景,應該是在比較寬裕的環境下所長大,而老大、老二,則是走過篳路藍縷的開家創業歷程。

當老二在楚國因殺人而被捕入獄後,范蠡原先屬意由老三拿鉅額的金錢去請楚國的莊生幫忙,另一個考量,也是相信老三不會因為吝惜這些錢財而壞事。但沒想到半路殺出個老大出來,並以死相逼,並說:「如果不讓我去救人,我就當場自殺。」大家拿老大沒轍,加上母親也出面說話了,大家只好陣前換將,改讓老大去進行救援任務。

老大到了楚國,把錢交給莊生後,一來覺得對方住的這麼偏僻,又看起來窮酸,深怕這麼大筆的錢就這樣被坑了。即便莊生一再交待,要老大趕快離開楚國、就算看到老二被放出來,也不可與他見面,但...老大始終沒有聽進去,他還是擔心莊生拿了錢不辦事,於是就偷偷在楚國的飯店住了下來,看看莊生是真有本事還是招搖撞騙。

另一方面,莊生收了錢後,就去皇宮找楚王。原來,莊生在楚國是個德望很高的人,一直深居淺出。莊生說服楚王為了讓楚國國運更亨通,所以要進行一次大赦,來積功德。沒想到,這事情進行的太順利了,大赦的消息很快就在楚國傳遍了。在飯店久候的老大也聽到這消息,但他並不知道是莊生在後面所籌劃,他只認為是弟弟運氣好,碰上這次大赦,而莊生則是撿現成的便宜,白拿了我們家這麼多錢。老大越想越不甘心,於是就去莊生家,把錢要回來。

老大這舉止,著實讓莊生怒不可言,擺明是太欺負人了。於是莊生表面上是退還了錢,但私底下則是跑去楚王那邊進讒言,挑明了陶朱公的二公子在楚國所犯的罪行,陶朱公現下正到處行賄楚國大小官員企圖要脫罪。當下,楚王做了個決定,先斬了陶朱公二兒子後,再來特赦。

最後,老大帶著巨額的錢財與老二的屍體返家了。


大兒子、小兒子,因出生的背景條件不同,對於金錢的態度也不一樣。老大曾經吃過苦,對於金錢,則是分文都不敢浪費;老三則是出生在家族比較富裕的年代,金錢對他而言,只是個工具,即便要捨去,也不會有像是要取了他性命的感覺。常言道:「富貴修行難,貧窮佈施難」。在陶朱公的這兩個兒子身上,感觸特別的多。曾經有本書,叫做《有錢人想的跟你不一樣》,書裡面不斷地在各個理財面向,陳述富人與窮人的不同觀點。格局不同,自然思考的面向也會不同。所以常常有人會戲說:「換了位置,就換了腦袋」。真的要跟他們喊冤平反一下,人家也是為了三餐能夠溫飽,環境所逼啊~

這句成語故事,到此約莫說盡了,但,天真的小朋友,一定會問,那這句成語到底是形容好事,還是形容壞事的呢?電視上的卡通,總是可以很清楚分辨誰是好人,誰是壞人的啊?其實,這句成語,真的有深度,他表面上是說有錢人的孩子,殺了人不會死(註二)。但其實是一種反諷的說法。譬如家鄉老母說過,以前有個人,曾經算命算出是皇帝命,一輩子吃穿不用愁,從此就開始好吃懶作,最終窮途潦倒。所以當有人看到你偷懶時,對你說:你還真是皇帝命啊!這時可能高興不起來了,因為這是反諷法。「千金之子,不死於市」,這句同樣也是。在元智大學經典沙龍裡,看到黃玫茵老師對於「竊鉤者誅,竊國者侯」、「千金之子,不死于市」說的很好(參考 06),光靠字面上的意思,會讓你誤解為:要做壞事,就要做最壞的;只要很有錢,殺人就不會死。但其實原意並非如此,而是一種反諷的手法。但這兩句,在司法不公、世道蕩然無存之際,反而造著字面的意思,更讓人能夠信服許多。小朋友的世界,是非善惡,都是非善即惡,但大人的世界就複雜許多,大忠似奸、大奸似忠。還是建議你多去看點卡通,人生會比較少煩惱,會比較快樂一些。



註一:《越對吳的作戰指導原則》

戰爭的要諦,在於要合乎天地的法則,並能順從陰陽變化而行動。敵人取得絕對優勢時,對我們便是屬於「陰」的法則,這時候要做持久性的隱忍以等待時機。

恢復優勢的時候,是屬「陽」的法則,我方可用疾風迅雷般的一擊,將敵人徹底的壓制住。敵人迫近時,要佯裝弱勢以引誘他們,讓他們掉入事先安排好的陷阱;敵人距離當尚遠時,則可以示之以威勢,阻止其妄動,要點是,要隨時相應著敵人的情勢做為對應,當敵人已準備好要拚命防守時,最好冷靜地思考智取的策略,絕不可以硬碰硬地進攻。敵人在引誘我們進攻時,一定要觀察清楚,並且做好固守陣地的準備。

發動戰爭時,則要顧及天. 地. 人三方面的條件。處「陽境」時,宜集結最大力量拚命一擊,處「陰境」時,則要盡力地暗中充實自己的人力和物力,絕對避免任何力量被削弱。掌握主導權時,要奮力攻擊,以徹底壓倒敵人,要設法把對方僅存的陽氣,剝削殆盡。主導權在敵人時,無論如何也不可以輕舉妄動,盡量保持所有的力量,這也是重要的處陰之道。懂得這種天道的自然法則,便可以應用自如地掌握住所有的作戰契機。

但是觀察情勢最忌諱主觀,心中有太多的目標和慾望,在評估時會過於樂觀,只看到機會而看不到危險,會失之於魯莽。心存恐懼或者逃避意願時,評估則傾向消極,只看到危險卻看不到機會,過度的小心也會把自己侷限在僵化的位置。

因此觀察必須客觀,不必有想法,不必急著評估,只要全心全意聆聽和觀察,心中保持絕對安靜,不必急著有答案。沒有自我的判斷,只有純粹的「看」和「聽」,沒有「看者」和「聽者」,便可以處於最客觀的位置。

註二:(出自:古文觀止-貨殖列傳序)

原文
故曰:「倉廩實而知禮節,衣食足而知榮辱。」禮生於有而廢於無。故君子富,好行其德;小人富,以適其力。淵深而魚生之,山深而獸往之,人富而仁義附焉。富者得勢益彰,失勢則客無所之,以而不樂。諺曰;「千金之子,不死於市」此非空言也。故曰:「天下熙熙,皆為利來;天下壤壤,皆為利往。」夫千乘之主,萬家之侯,百室之君,尚猶患貧,而況匹夫編戶之民乎﹗

譯文
所以,管仲說︰「國庫充實,百姓才懂得禮節;衣食豐足,百姓才能分辨榮辱。」禮節是在富有時產生的,貧窮時廢弛。因此,有統治地位的人富有,才會推行德政;百姓富有,才能調節自己的勞力。海深魚自然會聚居;山深百獸就自然會到那裡去;人富有仁義就會依附在他的身上。富貴的人得到權勢就更加顯赫,失去權勢,作客都無處可去,因此而沒有樂趣。諺語說︰「家有千金的人,不會因犯法而被處死於市曹。」這可不是一句空話啊。所以說︰「普天下的人熙熙而來,都是為了利,攘攘而去,也都是為了利。」那千乘的封國,萬戶的列侯,百室的大夫,尚且擔心貧窮,何況是百姓?






參考:
01:【TG 的紅茶書坊】「千金之子,不死於市」——范蠡的小故事
02:是谁要了范蠡儿子的命
03:范蠡与西施生有一个儿子
04:古文觀止-貨殖列傳序

05:有錢人想的跟你不一樣
     a.http://www.shukai.biz/2006/12/secrets-of-millionaire-mind.html(楚狂人)   
     b.http://www.books.com.tw/exep/prod/booksfile.php?item=0010316121 (博客來)

2011年12月7日 星期三

如何讓 radio 亮起來

使用 Visual Studio 設計 Web Form 頁面時,當我使用了 RadioButtonList 控制項,且將該控制項的 Enable 屬性設為 false 時,一般都會得到一個很醜且灰濛濛的介面。


是否將 radio 裡面的文字刻意指定顏色給它,就可以有所改善呢?於是我簡單的加了 <font color="red"> 在裡面。
<asp:RadioButtonList ID="RadioButtonList1" runat="server" Enabled="False">
 <asp:ListItem Value="1"><font color="red">世界是平的</font></asp:ListItem>
 <asp:ListItem Value="2"><font color="red">體驗經濟時代</font></asp:ListItem>
 <asp:ListItem Value="3" Selected="True"><font color="red">太極拳道幾</font></asp:ListItem>
</asp:RadioButtonList>

實驗結果出爐,結果是:沒採工,一點反應都沒有。但有趣的是,以 chrome 、firefox 來開啟頁面,竟然是「有起色的(是紅的)」...


這點差異,倒是蠻有趣的。進一步去檢視網頁的原始碼可以發現:當我將 radiobuttonlist 的 enable 設為 false 後,它所產生出來的 html code,幾乎每個 html tag 都可以發現 disabled="disabled" 的影子。 甚至連 <input id="RadioButtonList1_0" type="radio" 的外面都還包了一個 <span disabled="disabled">。原來,只要是 html tag 裡面有定義 disabled="disabled",則該 tag 的顏色,就會變成灰色,不管是哪個瀏覽器都一樣會有這個效果。只不過,當 tag 裡面,還有另一個 tag 時怎麼辦?對於 chrome、firefox 來說,他們分的比較細,他們允許每一個 tag 都有各自的呈現方式,外層 tag 並不會影響內層的 tag,大腸包小腸,誰說這兩個腸一定都非香腸不可呢?這問題的處理上,IE 就顯得簡化許多,只要是外層有設定 false,內層不管你怎麼設,都一定是灰的。甚至你可以做一個實驗,只要你在你的網頁的一開始就放一個 <span disabled="disabled">,並把 </span> 放到網頁內文的最後面,模擬將所有的頁面內容,通通都包進這個 <span disabled="disabled">,檢視一下結果會發現,使用 IE 瀏覽器,全部的控制項都變成灰色了,彷彿都不能動了一樣。但可別被它蒙蔽了,裡面的輸入方塊、按鈕...,每一個都還是可以敲、可以按,只不過顏色是灰色的而已;這奇特現象,在 firefox、chrome 則是不會見到的。



<table id="RadioButtonList1" disabled="disabled" border="0">

<tr>

<td><span disabled="disabled"><input id="RadioButtonList1_0" type="radio" name="RadioButtonList1" value="1" disabled="disabled" /><label for="RadioButtonList1_0"><font color="red">世界是平的</font></label></span></td>

</tr>
<tr>

<td><span disabled="disabled"><input id="RadioButtonList1_1" type="radio" name="RadioButtonList1" value="2" disabled="disabled" /><label for="RadioButtonList1_1"><font color="red">體驗經濟時代</font></label></span></td>

</tr>
<tr>

<td><span disabled="disabled"><input id="RadioButtonList1_2" type="radio" name="RadioButtonList1" value="3" checked="checked" disabled="disabled" /><label for="RadioButtonList1_2"><font color="red">太極拳道幾</font></label></span></td>

</tr>

</table>

所以,依據上面的說法,在 IE 瀏覽器,只要 radio button 不被 <span disabled="disabled"> 包圍住,理論上也是可以擺脫灰色的命運。那就再次試試看...
<input type="radio" value="A" name="ra1" checked="checked" disabled="disabled"><font 

color="red">paldin </font>
<input type="radio" value="A" name="ra1" disabled="disabled"><font color="red">lttlab </font>




還果真如此,所以在 IE 瀏覽器上,其實也是可以讓 disabled 的 radio button 有不一樣的顏色,只是我使用 Visual Studio 的 RadioButtonList 控制項,會自動幫我加入許多並非我想要的 html tag,導致不管我怎麼調顏色,都無法上色。

說了這麼多,那在 IE 瀏覽器上,是否有機會更改那些 Enable 設為 false 的控制項呢?由於我功力還不夠深厚,目前無法回答這問題,但偷吃步倒是有一招。

為了避免 IE 處理 disabled 屬性與其他人不同調,於是我就在頁面的開發上,就不事先去定義 RadioButtonList 的 Enable 屬性,而且也不從後端去設定它,改由透過前端的 javascript 或 jQuery 來完成。

ex:  $("input[type=radio]").attr("disabled", "disabled");

如此,只要一行指令,就可以讓所有頁面上的 radio button 無法作用,又能保有光鮮亮麗的色彩。

2011年11月28日 星期一

讓 jQuery UI 的 DatePicker 多個 clear 按鈕

Keith Wood 寫了不錯的日曆挑選元件,同時也被 jQuery UI 收錄為官方版的挑日期方案。所以我們只要在 datepicker 頁面,就可以找到。然而,如果你細心的去比較 Keith Wood 的個人網站,會發現該作者目前所發表的日曆挑選元件,似乎在功能上,比 jQuery UI 所發佈的還要多。舉例來說,下面的日曆元件是來自於 Keith Wood 目前的版本 4.0.6


有沒有發現,他有一個 Clear 的鏈結,點下去,會將目前的日期輸入方塊上的資料清掉。很重要嗎?如果你的日期輸入方塊,有設定為 readOnly = true 時,這種需求的機會應該就會變高了。那 jQuery UI 的有提供嗎?
目前 jQuery UI 的版本是:1.8.16,很不巧的,沒有,他並沒有 clear 的功能。但如果你真心喜歡一個人的話,理應可以包容對方不足的地方。但前提是,要先努力過,努力甚麼呢?先給他去整形一下吧...


雖然 jQuery UI 目前的版本並沒有提供,但熱心的工程師,總是會想出些「成人之美」的方案。我在 http://bugs.jqueryui.com/ticket/3999 看到了很多人的抱怨,但也發現了一個有建設性的解法,雖然要多寫幾行程式,但能抓到老鼠的都算是好貓啦!




<script type="text/javascript">
$(function(){
    $(".pickdate").datepicker({
        changeMonth: true,
        changeYear: true,
        dateFormat: 'yy/mm/dd',            
        showButtonPanel: true

    });

    // hack to add clear button
    // 增加清除按鈕 -Start (Ref. http://bugs.jqueryui.com/ticket/3999)
    //wrap up the redraw function with our new shiz
    var dpFunc = $.datepicker._generateHTML; //record the original
    $.datepicker._generateHTML = function (inst) {
        var thishtml = $(dpFunc.call($.datepicker, inst)); //call the original

        thishtml = $('<div />').append(thishtml); //add a wrapper div for jQuery context

        //locate the button panel and add our button - with a custom css class.
        $('.ui-datepicker-buttonpane', thishtml).append(
 $('<button class="\
  ui-datepicker-clear ui-state-default ui-priority-primary ui-corner-all\
  "\>Clear</button>'
 ).click(function () {
     inst.input.attr('value', '');
     inst.input.datepicker('hide');
 })
);

        thishtml = thishtml.children(); //remove the wrapper div

        return thishtml; //assume okay to return a jQuery
    };

    // 增加清除按鈕 -End

  
  
});
</script>
如此折騰一番後,就可以多生出一個 Clear 按鈕了。

測試程式 [下載]

參考:
01:http://bugs.jqueryui.com/ticket/3999
02:Keith Wood,http://keith-wood.name/index.html

2011年11月8日 星期二

利用 FileStream 讀檔、寫檔


在 C# 裡,透過 FileStream 可以很容易地完成檔案的讀/寫動作,有時候真的會覺得,它其實不難,但真要從無到有卻沒得參考還真的有點不方便,所以整理了一下基本的使用方式。更多有關檔案操作方法,可以參考《[C#] 檔案讀寫》這篇文章,寫得很詳細。


/// 
/// 將檔案寫到 Byte[]
/// 
/// 

/// 
private byte[] File2Byte(string strFilePath)
{
    FileStream fileStream = null;
    Byte[] fileBytes = null;

    if (File.Exists(strFilePath))
    {
        try
        {
            fileStream = new FileStream(strFilePath, FileMode.Open, FileAccess.ReadWrite);
            fileBytes = new byte[(int)fileStream.Length]; //設定 fileBytes 的長度
            fileStream.Read(fileBytes, 0, fileBytes.Length); //將 filestream 資料讀到 fileBytes 
        }
        catch
        {
                    
        }
        finally
        {
            fileStream.Close();
            fileStream.Dispose();
        }
    }

    return fileBytes;
}


在 MSDN 的《FileStream 類別》有提到:「請確定對所有 FileStream 物件呼叫 Dispose 方法,尤其是在磁碟空間有限的環境中更應如此。如果沒有可用的磁碟空間,且在 FileStream 完成之前沒有呼叫 Dispose 方法,則執行 IO 作業可能會引發例外狀況。」雖然目前沒有直接可實驗的環境,就姑且信之,乖乖的加上一行 Dispose。

/// 
/// 將 Byte[] 資料寫到檔案
/// 
/// 

/// 

/// 
private bool Byte2File(byte[] bRead, string strNewFilePath)
{
    FileStream fileStream = null;
    try
    {
        fileStream = new FileStream(strNewFilePath, FileMode.OpenOrCreate);
        fileStream.Write(bRead, 0, bRead.Length);
    }
    catch(Exception ex)
    {
        Response.Write(ex.Message);
        return false;
    }
    finally
    {
        fileStream.Close();
        fileStream.Dispose();
    }

    return true;
}


呼叫讀檔/寫檔函式:
protected void btnFile2Byte_Click(object sender, EventArgs e)
{
    //設定檔案來源
    //string strFilePath = "D:\\upload\\projAply\\ann_e3wdwz10.xls";
    string strFilePath = @"D:\upload\projAply\ann_e3wdwz10.xls";

    //將來源檔案寫到 Byte[] bRead
    Byte[] bRead= File2Byte(strFilePath);

    //將 Byte[]  bRead 裡的資料寫到檔案
    Byte2File(bRead, "D:\\upload\\projAply\\ann_test.xls");
}


在設定檔案來源的地方,特別用了一個 「@」符號,其實是故意的。主要是想要特別分享這個好方法。原先使用單純的字串時,如果遇到反斜線(\)時,則必須使用雙反斜線(\\)來代表。但如果在字串前面加上 @ 符號後,後面的字串除了引號(")需要改用雙引號("")來替換之外,就不再需要考慮逸出字元的處理了,甚至連跨越數行都沒有問題。詳見:C#中的@符號


Ref:

01.
[C#] 檔案讀寫
http://blog.xuite.net/autosun/study/32576568

02.
FileStream 類別
http://msdn.microsoft.com/zh-tw/library/system.io.filestream(v=vs.80).aspx

03.
C# byte[]和文件FileStream相互转化
http://www.cnblogs.com/wskfire/archive/2007/11/30/978212.html

04.
C#中的@符號
http://tc.wangchao.net.cn/bbs/detail_149142.html

05.
2.4.4.5 字串常值
http://msdn.microsoft.com/zh-tw/library/aa691090(v=vs.71).aspx

06.
C# 字串變數, 如何包含雙引號或反斜線
http://www.allenkuo.com/GenericArticle/view.aspx?id=28

人在低谷,只有往上看的選擇;人在高峰,卻有往下環顧的責任



難免有時候,會遇到低潮、或令自己難過不已的事情,就好比經歷了一場大風雪,雖然你不知道何時會結束,但可以肯定的,是它終究會過去。「面對它,接受它,處理它,放下它。」,嚴然是處理問題的成熟作法,但並沒有人要求你一定要理性,其實也可以任性一些些。當這突如其來的問題發生時,你,會怎麼處理呢?

以下列出幾個常見的作法:


  • 克服難堪情緒的最好方法,是儘快把事情的來龍去脈講給周遭的人聽。你會發現,原來支持你的人比你想像還要多,而且別人不只不會責備你,還很樂意幫助你。此外,講的次數越多,你的情緒波動會漸漸變小,然後逐漸接受這件事。不管發生什麼事,盡量別讓自己的情緒受影響,這樣才能有清楚的腦袋,對下一步做策略思考。 
  • 自己不好意思開口對別人訴說,那就跟神說,或跟自己的宗教信仰說。 這會比一個人悶在心裡頭好很多。
  • 觀功念恩。觀看對方的好處,感謝對方帶給你的成長與收穫。看別人的功德,別人不一定有好處,但自己一定有好處;看別人的過失,別人不一定受害,自己一定受害。
  • 「境由心生,聖人轉心不轉境,凡人轉境不轉心。事來心始現,事去境隨空。虛靈無我,捨己從人。」事情的本身,並沒有所謂的絕對。若以受害者的角度去看它,你會更難過;但如果你相信無限生命(甚至可以延伸到下一世、下二世),它就會只是生命中的一個過客而已。緣聚而來,緣散而去,聚散乃人生常態,有緣成為同路人,到站各自奔東西。
  • 「欲知前世因,今生受者是,欲知來世果,今生做者是。」如果前世有造業,今世來償還,天經地義,也沒什麼好難過,所以要歡喜去受。如果前世沒造業,今世來累積福德資糧,你賺到了,所以更要歡喜去受。如此,幹麼還難過啊!
  • 適度的增加可以轉移注意力的活動。如多參加戶外活動、或多承擔些額外工作,讓自己沒時間悲傷。


是否您還有更好的方法呢,聆聽專線(暫不提供 0800),請直接填寫意見回覆就好...






參考:
01.Cheers 125 期 「只要9招,躍升職場要角(全文)」
02.觀功念恩 開啟心靈快樂之鑰






王師傅坐公共汽車到上海市嘉定區高潮村。
因沒去過所以剛過二站就開始問車掌小姐:'高潮到了沒有?'
車掌小姐答:'沒有'
過了二站後,王師傅又問了: '高潮到了沒有?'
車掌小姐答:'沒有。'
沒過幾分鐘,王師傅又問:'高潮到了沒有?'
這時,車掌小姐實在是不耐煩了。
高聲地回答道:

高潮到了我會叫!!!



2011年11月3日 星期四

動態切換 Master Page

隨著心情、節日或角色而變換網頁色系,似乎蠻符合鮮明的個人風格。這樣的需求,換一換 css 應該就可以完成。但如果連排版也要重新建構,例如由原先的 Menu Bar放左邊,改成 Menu Bar 放上面,這樣 ... 心情就不會再美麗了。


樣板A
樣板B
為了能夠動態(或根據某些條件)來切換網頁樣板,有個比較簡單的方式,就是透過 Master Page 的更換來完成。也就是說,事先設計好幾個 Master Page A, B, C, D ...,最後根據某個規則來載入適當的 Master Page 就可以達成簡單的樣板切換功能了。而每個樣板所需要的 CSS 或 javascript ,也可以依據不同的 Master Page 而各自撰寫。

自己參考了 Ryan 的 「Dynamically Loading Master Pages in ASP.NET 2.0」文章,整理了一些測試程式。


首先建立 Dynamic 類別,為了讓需要動態切換的頁面來繼承。在程式中,是假設日後的樣板資訊是留存在 DB ,所以這邊會去 DB 抓資料回來。
 
namespace CMaster
{
    public class Dynamic:System.Web.UI.Page
    {
        protected override void OnPreInit(EventArgs e)
        {
            string strMaster = GetMasterFromDB();

            if (!strMaster.Equals(string.Empty))
            {
                base.MasterPageFile = strMaster;
            }

            base.OnPreInit(e);
        }


        //模擬從 DB 抓取 Master 設定
        private string GetMasterFromDB()
        {
            return "~/SK02.Master";
        }
    }
}
接著將需要動態切換 Master Page 的頁面,將其頁面的繼承改為 Dynamic ,以自己的範例來說,就是修改 MyPage.cs 如下:
namespace CMaster
{
    public partial class MyPage : Dynamic
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
    }
}
這裡將 原先的 public partial class MyPage : System.Web.UI.Page 改成
 public partial class MyPage : Dynamic

如此就可以完成動態切換 Master Page 的需求了。

在 Ryan 的文章中有提到透過設定 web.config 的 pageBaseType 可以達到一次設定所有頁面都支援動態切換 Master Page,但使用這方法要注意,你的程式必須是使用 Inline mode 開發,如果是使用 Code Behind (預設都是採 Code Behind),則設定 web.config 這種方式就會失效囉。



參考:

2011年10月26日 星期三

殺了我吧



兩千五百多年前,越王勾踐在夫椒被吳王夫差大敗後,兩次乞和才換得國家的存續,但所付出的代價並不斐,不僅要貢獻金銀財寶、妻兒子女,連勾踐自己,也要入吳為奴。就在勾踐入吳當天,面對越國臣民的擁戴與不捨下,一旁的范蠡看出了勾踐內心的百感交集,為了中興大業,范蠡告訴勾踐一段話:

「君王您必須完全殺死心中那個『我』,才能消除所有的意念。您不是感到生不如死嗎?那就殺死心中那個『我』吧!」

勾踐心中不解,暗暗說道:「你這傢伙,是要落井下石是嗎?」

范蠡從勾踐的眼神,似乎嗅出了一股不安,急忙解釋到:「殺死自己的意念、理想、希望及期待,內心裡完全沒有『我』,不再以『我』的意志去生活,只是隨波逐流,無論發生什麼事情都能夠接受,成為一個『無』,那便沒有『誰』必須去承擔這個苦難了。這樣子,身體隨遇而安,跟河中的魚蝦一樣,不為什麼而活著,不必有抗拒,便不必有忍受。想要度過這場大苦難,唯一的方法就是順著天意,不必有自己的任何想法。」

范蠡口中所講述的內容,以現代人來看,很難不被冠上「消極」、「懦夫」的封號,但在范蠡所出生的年代諸子百家爭鳴,也剛好盛逢其世,而其所提出的建議,恰巧不離老子所倡導的:道法自然。又以其中「無為而無所不為」最為貼切。我們可能會覺得范蠡怎會提出這等懦弱的策略呢?但歷史的結局給了最有力的證明,一個承受幾近亡國的國君,透過這柔弱的策略,最後滅掉吳國成為春秋時代最後一個霸主,在在驗證著老子「柔弱勝剛強」的理路。

老子第十三章有云:

「何謂貴大患若身?吾所以有大患者,為吾有身;及吾無身,吾有何患?」

摘錄王邦雄先生的解釋:

身貴就是大患的理由何在呢?之所以會有大患的理由,就是因為我的心知執著了自我,也背負了自我,要高貴自己,也要富麗自己,高貴靠權勢,富麗靠名利,名利權勢在人間街頭,也就逼自己去打天下,而天下如此之大,天下人如此之多,豈不是成為自身最大的負累跟壓力嗎?等到那一天,當我去除了對自身的執著,不以自我為中心,也不自我膨脹,不求自身的高貴與富麗,也不用去打天下,不受權勢的羈絆與名利的牽引,放下不就自得了嗎?


所以,當你無計可施、或承受巨大痛苦時,兩千五百年前范蠡所說過的話,或許今日也一樣對你有所幫助。


參考:
01.千秋商祖 范蠡
02.范蠡人物簡介
03.老子道德經的現代解讀

2011年10月19日 星期三

好人贏家卡




Cheers 125 期,摘要了一段名為「好人贏家卡」的文章,偷懶放逸時,隨時惕厲一下,有助消解渾渾噩噩的症狀。

要成為贏家,一定要有會權謀、工心計的DNA嗎?不, 史丹佛 教授傑夫瑞‧菲佛認為,以下這7項才是決定你能否在現實職場中勝出的主因。

□雄心
成功需要投入心思與努力工作,一定要有雄心做為動力,才可能投入那些心思、做必要的犧牲。雄心(一心一意要攀到權力高峰)可以幫你克服放棄的念頭或避免你臣服於惱怒。

□精力
精力可以做到3件事,有助於權力建立。
第1,精力會激發別人,讓別人更努力;
第2,精力充沛就能長時間投入,也就愈有利於事情的達成;
第3,精力充沛的人比較容易被拔擢,因為投入大量精力就代表高度認同組織,忠誠度較高。

□專一
專一於一個產業或一家公司,這會讓你深入了解該領域,培養人脈。
進一步,你應該專注在工作或職務範圍內最關鍵的部份,也就是最能影響事情完成與否,以及別人對你和你工作效能的觀感部份。

□了解自己
沒有反省,就沒有學習與成長。有條理的反省是需要發時間的,也需要有紀律地全神投入。做筆記、思考自己的行為,都對朝管理者邁進有幫助。

□自信
人們在判斷權力大小與決定該不該順從時,會看對方的一舉一動。表現得自信、有知識,有助於建立影響力。

□替別人著想
有時候人之所以不替別人想,是因為太在乎最終目標,不想把精力發在爭取別人支持,或降低他們反對的可能性上。但實際上,站在別人的立場想,不僅不會讓你離目標愈來愈遠,反而是讓你前進的最佳方式。

□容忍衝突
如果你能有效解決難堪的衝突及高壓下的場面,你就擁有一項大多數人沒有的優勢。


推薦書:


2011年9月27日 星期二

透過 css 設定讓頁面的高度達到100%

簡單的在頁面上放一個 table
<table border="1" style="border-collapse: collapse;">
<tr><td>aaa</td></tr>
</table>
如果注意觀察,這個 table 的頂端與左邊都會留下空白。當你的頁面有設定背景顏色時,這些空白就會顯得非常突兀。 這時可以透過設定 body 的 margin 與 height 來完成。
<style>
body{ 
margin:0px; 
height:100%; 
} 
</style>
對 body 設定 margin:0px 與 height:100% 之後,就可以達到高度 100% 的效果。
參考:
01.[CSS]網頁標準化實現高度100%
02.css中height:100%不起作用的解决方法

2011年9月26日 星期一

關於在 64位元的 Win7 上匯入 excel 的不堪往事

以前對的事,現在不一定對。自從電腦從 XP 升級到 win7、從 32 位元升級到 64 位元後,這感觸就越來越深了。

以簡單的程式範例來說:


.aspx
<input id="File1" runat="server" name="File1" size="42" style="width: 300px" type="file">
<asp:Button ID="btnImport" runat="server" Text="匯入" onclick="btnImport_Click" />
.aspx.cs
protected void btnImport_Click(object sender, EventArgs e)
{
    //將要匯入的 excel file,先儲存在 IIS Server 的系統暫存目錄.
    HttpPostedFile uploadFile = Request.Files[0];
    string strFileSavePath = Path.GetTempPath();
    string xlsFullName = string.Format(@"{0}/{1}.xls", strFileSavePath, Guid.NewGuid());
    uploadFile.SaveAs(xlsFullName);

    #region //讀取 Excel format data.
    string OleConStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + xlsFullName + ";Extended Properties='Excel 8.0;HDR=No;'";
    OleDbConnection OleCn = new OleDbConnection(OleConStr);
    OleDbCommand OleCmd = new OleDbCommand();
    OleCmd.Connection = OleCn;
    string strSQL = @"SELECT * FROM [Sheet1$]";
    OleCmd.CommandText = strSQL;

    string strData = "";
    int i = 0;
    try
    {
        OleCn.Open();
        OleDbDataReader OleDr = OleCmd.ExecuteReader();
        while (OleDr.Read())
        {
            if (i > 0)
            {
                string strRed = OleDr[0].ToString().Trim();
                if (strRed != "")
                {
                    strData += string.Format("{0},", strRed.Trim());
                }
            }
            i += 1;
        }
    }
    catch (Exception ex)
    {
        //如果檔案存在砍掉此暫存檔案
        if (File.Exists(xlsFullName))
            File.Delete(xlsFullName);

        String scriptString = string.Format(@"
    <script language=JavaScript>
    <!-- begin 
    alert('Excel格式錯誤! 詳細資訊:{0}'); 
    //end -->
    </script> 
    ", ex.Message.Replace("'", "\\'"));
        ClientScript.RegisterStartupScript(GetType(), "msg", scriptString);
        return;
    }
    OleCn.Close();
    #endregion

    Response.Write(strData);

}
如果你建立 web 專案時是以 「File System」方式,則執行匯入功能時,可以正常執行。但如果你建立 web 專案是以「Http」方式,則執行匯入功能時,有可能會出錯,為何說有可能呢?因為這問題是由 IIS 設定所導致的。先看看這錯誤訊息長得怎樣: 

Microsoft.Jet.OLEDB.4.0 提供者並未登錄於本機電腦上。 

原來主要原因,是因為Microsoft Jet 不支援 64 位元的版本,因為 Win7 裝完 IIS 後,預設是以 64 位元的方式來啟動應用程式。可以檢視一下自己的 IIS 設定:

如果「啟用32位元應用程式」為 False,則把它改成 True,讓你的專案是以32位元的模式來執行,就可以正常讀取 excel 資料了。

如果你不是使用 Http 的開發模式,也同樣出現「Microsoft.Jet.OLEDB.4.0 提供者並未登錄於本機電腦上。」錯誤訊息,建議可以參考這篇「Microsoft.Jet.OLEDB.4.0 提供者並未登錄於本機電腦上」文章,或參考下方的[補充20120809]。

此外,如果使用者將 office 升級到 2007以後,預設的 excel 檔名已經由 .xls 變成 .xlsx,當我們使用 Microsoft.Jet.OLEDB.4.0 ,會發生「外部資料表不是預期的格式」錯誤訊息,為了能夠讓匯入 excel 的功能跟的上微軟更新的腳步,必須到以下網站下載:

或是 Google 以下關鍵字:AcessDataBaseEngine


你可能會找到:

AccessDatabaseEngine.exe
AccessDatabaseEngine_x64.exe

一開始我以為是要用 _64 .exe 的版本,但下載安裝後,竟然出現:
由於你目前已安裝 32 位元的 Office 產品,因此無法安裝 64 位元版本的 Microsoft Access Database Engine 2010...

我當時還傻傻的把我的 office 移除,然後去找 64 位元的 office 來裝,最後因為找不到 64 位元的 office 而作罷(到底有沒有 64 位元的 office ,至今我還是沒有找到)。這時候,你只要安裝 AccessDatabaseEngine.exe 版本就可以,別花時間去移除你的 office 了。

安裝完畢後,原來的程式,有個地方需要調整:

將原先:

string OleConStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + xlsFullName +
";Extended Properties='Excel 8.0;HDR=No;'";

改成:
string OleConStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + xlsFullName + ";Extended Properties='Excel 12.0 Xml;HDR=No;'";


這樣就可以順利完成 excel 匯入功能了。



[補充20120809]
如果不是使用 Http 的開發模式,可以在專案的專案名稱屬性裡,將建置(Build)裡的平台目標(Platform target) 設為 x86。

如下圖:


參考:

2011年9月21日 星期三

標點符號自救法


以前用 office word,都會習慣要設定好符號表,但如果不是在 word 裡面編輯文章且需要使用到標點符號,就會覺得有點不方便。如果你所使用的中文輸入法有提供標點符號,這就不會有問題,但如果你在沒有額外安裝中文輸入法的電腦(如:公用圖書館),學會野外基本求生術,其實是一件很重要的事情。

目前大部分微軟的作業系統(xp、win7),只要安裝完後,基本上都會出現新注音、新倉頡之類的輸入法,如果你沒打算安裝其他輸入法,當你需要輸入標點符號時,可以用以下方式輸入全形或半形符號。

一、如果是基本需求,如:

,。;、【】


可以左手壓著 Ctrl 鍵,右手試著敲「,」、「.」、「;」、「'」、「[」、「]」
就可以出現上面的符號。

二、如果是中度需求,如:

「『〔︹︻﹁﹃﹝[「   Ctrl+[  然後再按 ↓挑選
」』〕︺︼﹂﹄﹞]」   Ctrl+]  然後再按 ↓挑選
‘’′                Ctrl+'  然後再按 ↓挑選
‧                    Ctrl+.  然後再按 ↓挑選

二、如果是中上需求,如:


\↖↘﹨
|↑↓∣∥︴
±﹢≠≡≦≧
‥…←→﹉_ ̄
*×※╳﹡
︿〈《︽﹤<
€¢£¥
@⊕⊙㊣

可先按 ` 鍵一下(位於 Esc 下方,Tab 上方),
再試著敲:
Shift+;
Shift+\
\
Shift+\
Shift+=
-
Shift+8
Shift+4
Shift+2


三、重度使用者需求,如:
♠♢♣

這需要打開內碼符號表來輸入。
先按 ` 鍵一下(位於 Esc 下方,Tab 上方),
再按 U
接著輸入內碼符號。

可以參考網友所整理的內碼符號表:新注音符號表♪




2011年9月20日 星期二

處理 ASP.NET 匯出 Excel 時,檔名或內容出現亂碼



匯出 Excel 最讓人頭疼的事,就是出現亂碼,尤其是中文字的處理,還分簡體與繁體。如果碰上 big-5 沒定義的字,例如「炁」,又要開始掉頭髮了。為了讓大家擁有豐厚的髮量,路上不被人叫阿伯,整理了目前測試後有效的解決方式,早晚服用,三日見效,7天後讓你在夜市從街頭逛到巷尾都被攤販老闆喊「帥哥」!


    StringBuilder sb = new StringBuilder();
    protected void Page_Load(object sender, EventArgs e)
    {
        BindData();

        //匯出至 excel format.
        Response.Clear();
        
        string strFileName = "导出后";
        
        if(Request.Browser.Browser=="IE")
            strFileName = Server.UrlEncode(strFileName);

        Response.AddHeader("Content-Disposition", "attachment;filename="+strFileName+".xls");
        Response.ContentType = "application/vnd.ms-excel";

        Response.Write(sb.ToString());

        Response.Flush();
        Response.End();

    }

    private void BindData()
    {
        sb.Append("<html>");
        sb.Append("<head>");
        sb.Append("<style type='text/css'>");
        //將所有td的欄位格式改為"文字"
        sb.Append("td{mso-number-format:\"\\@\";}"); 
        sb.Append("</style>");
        sb.Append("</head>");
        sb.Append("<body>");
        //避免內容出現亂碼
        sb.Append("<meta http-equiv=Content-Type content=text/html; charset=utf-8>"); 
        //此處可撰寫迴圈讀取資料--開始
        sb.Append("<table>");
        sb.Append("<tr><td>炁</td></tr>");
        sb.Append("</table>");
        //此處可撰寫迴圈讀取資料--結束
        sb.Append("</body>");
        sb.Append("</html>");

    }
下載 Excel 檔名的部分,參考了保哥的建議,只針對 IE 瀏覽器進行 Server.UrlEncode()。而內容的部分,則是增加一行:

<meta http-equiv=Content-Type content=text/html; charset=utf-8>

將所有內容都以 utf-8 編碼,不再出現有些中文字無法顯示的情況。

此外,提供了 style 設定,讓匯出的 Excel 都能夠以「文字」的格式呈現,這對於有數字的欄位很有幫助。


參考:
01:ASP.NET 如何設定強制下載檔案並正確處理中文檔名的問題
02:檔案下載或開啟時出現亂碼檔名(不支援簡體)

2011年9月16日 星期五

讓 GridView 的 checkbox 狀態於分頁後還能保留


當 GridView 為每一筆資料列擺上 checkbox 時,別以為這樣對 user 很貼心喔,其實是夢靨的開始。 因為聰明的 user 在換頁後很快就會發現,前一頁有勾選的資料,在換頁之後,勾選狀態就不見了。原本你期待的是讚美與鼓勵,一夕間就變成 bug 與缺失了。想到下班後還要繼續加班改程式,所言至此 ,就不禁潸然流下男兒淚了...

不過,寫程式的最高心法就是:Copy Right (Copy is right,拷貝是對的)。往好處想,至少下次再遇到同樣的問題時,就可以不用再這麼辛苦從無到有了。如此累積下去,幾年後,每個人肯定都會身懷絕技。於是將這次解決的方法寫下來,日後再遇到同樣問題,有時間的話可以再去進一步最佳化;如果沒時間,至少也不會開天窗。 

我參考了網路上的文章,針對這問題提出兩種解決的版本,一種是從後端(server side)來處理,另一種則是從前端(client side)來處理。兩者的差別,在於勾選後是否會觸發 postback。當然,個人是比較偏好 client side 來處理,主要是因為程式碼比較簡潔、程式執行比較快速。

 ------ server side -------
說明:
將已勾選資訊存放在 List<string> lcb ,並將它透過 viewstate 來包裝。在 gridview 的 RowDataBound 事件,針對每個 checkbox 去註冊 GetPostBackEventReference(),讓 checkbox 一被勾選就會觸發 postback,同時將唯一可識別的資訊當作 postback 的參數。並於 Page_Load 攔截所 有 postback 事件,判斷是否是 checkbox 所發出,如果是,就更新 List<string> lcb 與 gridview 上 checkbox 的勾選與否資訊。

 .aspx
        <asp:GridView ID="gv" runat="server" AutoGenerateColumns="False" 
            EnableModelValidation="True" AllowPaging="True" DataSourceID="dsData" 
            onrowdatabound="gv_RowDataBound" PageSize="5">
            <Columns>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:CheckBox ID="cb" runat="server" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="id" HeaderText="ID" />
                <asp:BoundField DataField="name" HeaderText="Name" />
            </Columns>
        </asp:GridView>
    </div>
.aspx.cs
    List<string> lcb = new List<string>();

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ViewState["cbList"] = lcb;
        }

    

        string strTarget = "" + Request.Form["__EVENTTARGET"];
        string strCtl = strTarget.Split('$')[strTarget.Split('$').Length - 1];
        string strArg = "" + Request.Form["__EVENTARGUMENT"];

  
        HandleEvent(strCtl, strArg);
    }
    protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            lcb = (List<string>)ViewState["cbList"];
            CheckBox cb = (CheckBox)e.Row.FindControl("cb");           
            cb.Attributes["OnClick"] = this.ClientScript.GetPostBackEventReference(cb, 

DataBinder.Eval(e.Row.DataItem,"id").ToString());

            if (lcb.Find(x => x.Equals( DataBinder.Eval(e.Row.DataItem, "id").ToString

().Trim())) != null)
                cb.Checked = true;
            else
                cb.Checked = false;
        }
    }

    private void HandleEvent(string strCtl, string strArg)
    {
        switch (strCtl)
        {
            case "cb":
                UpdateCBList(strArg);
                break;
        }
    }

    private void UpdateCBList(string strArg)
    {
        lcb = (List<string>)ViewState["cbList"];
        if (lcb.Find(x => x.Equals(strArg)) == null)
        {
            //no match,insert
            lcb.Add(strArg);
    
        }
        else
        {   
            //match,remove
            lcb.Remove(strArg);
        }

        //final
        ViewState["cbList"] = lcb;
       
    }
------ client side -------
說明:
在 gridview 的 RowDataBound 事件,將每一個 checkbox 都加上 key 的屬性,裡面存放唯一且可識別的資訊。再透過 jQuery 為每個 checkbox 註冊勾選時都要觸發函式:UpdateHiddenValue()。在這函式裡,會判斷被觸發的 checkbox 的 key ,是否已存在於隱藏欄位 hValue (注意,必須將這隱藏欄位加上 runat="server",即使分頁後,依然可以保存 hValue 裡面的值),如果不存在,則將 key 值加入 hValue ,否則則從 hValue 裡面移除。最後,讓 DataGridView 裡的 checkbox 都隨時與 hValue 保持勾選與否的資訊同步。

 .aspx
<head runat="server">
    <title></title>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script>
        $(function () {
            //定義 checkbox 被點選時所要觸發的動作
            $("input[id$=cb]").click(function () { UpdateHiddenValue(this.key); });

            //將隱藏欄位 hValue 的值與 DataGridView 的 checkbox 作對應更新
            $("input[id$=cb]").each(function (i) {
                if ((',' + $("input[id*=hValue]").val()).indexOf(',' + $(this).attr('key') 

+ ',') > -1) {
                    //已存在,將 checkbox 打勾
                    this.checked = true;
                }
                else {
                    //不存在,將 checkbox 勾選取消
                    this.checked = false;
                }
            });
        });


        function UpdateHiddenValue(strInput) {
            if ((',' + $("input[id*=hValue]").val()).indexOf(',' + strInput + ',') > -

1) {
                //已存在,將輸入的值從隱藏欄位 hValue 移除
                var v = ',' + $("input[id*=hValue]").val();
                v = v.replace(',' + strInput + ',', ',');
                v = v.substr(1, v.length - 1);
                $("input[id*=hValue]").val(v);
            }
            else {
                //未存在,將輸入的值加入隱藏欄位 hValue 
                $("input[id*=hValue]").val($("input[id*=hValue]").val() + strInput+',');
            }          

        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:GridView ID="gv" runat="server" AutoGenerateColumns="False" 
            EnableModelValidation="True" AllowPaging="True" DataSourceID="dsData" 
            PageSize="5" onrowdatabound="gv_RowDataBound">
            <Columns>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:CheckBox ID="cb" runat="server" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="id" HeaderText="ID" />
                <asp:BoundField DataField="name" HeaderText="Name" />
            </Columns>
        </asp:GridView>
        <input type="hidden" id="hValue" runat="server" />
    <asp:XmlDataSource ID="dsData" runat="server" DataFile="~/data.xml">
    </asp:XmlDataSource>
    <div>
    
    </div>
    </form>
</body>
.aspx.cs
    protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            CheckBox cb = (CheckBox)e.Row.FindControl("cb");           
            cb.InputAttributes["key"] = string.Format("{0}", DataBinder.Eval

(e.Row.DataItem, "id"));
        }

    }
參考:
01:利用ASP.NET的HIDDENFIELD記錄GRIDVIEW的CHECKBOX狀態,並且加入全選、取消全選、分頁保留CHECKBOX狀態,達到類似GMAIL的郵件清單功能
02:GridView 欄位 CheckBox 全選及取消全選
03:測試程式下載

2011年9月15日 星期四

玻璃罐打不開怎麼辦?


記得以前分享過如何處理超級難開的玻璃罐頭,那時候我只用吹風機吹一下瓶蓋,就可以輕鬆打開了。但今天還真的讓我遇上狠角色了,不開就是不開。正當我要學劉備摔阿斗的那一幕時,突然想起:「一天一 Google ,百萬 g 民站起來」的廣告。還真的找到一篇「罐頭打不開怎麼辦」的文章,裡面有提到用門板夾著的方式,自己跟廁所的門板夾了許久,還是打不開。最後在抽屜看到一個開罐器,拿著尖銳的一邊用力去扳瓶蓋較大的縫隙處,聽到「啵」的一聲後,就可以輕鬆旋開蓋子了。


雖然一開始會擔心蓋子會不會因此而不能使用,但其實只要力道控制好,只需讓空氣流進玻璃罐內,就可以輕鬆打開了。目前我看了一下我的蓋子,是沒有發現有嚴重變形的地方。

參考:
01: 罐頭打不開怎麼辦
02:很難轉開的玻璃罐頭

2011年9月7日 星期三

喔,是這樣嗎?



在職場上,有時不免碰到處處跟你作對的人。近日一個朋友也是面臨如此困境,對方老是找他麻煩,即便茶水間狹路相逢,擠著笑臉跟對方打招呼,人家還把你當空氣一樣視而不見。我這朋友三天兩頭的為此大生悶氣。

最近剛好看到一篇白隱禪師的事蹟,一方面說給朋友聽,其實也是說給自己聽。


白隱禪師是一個過著純潔生活的人。

鄰居中有一位美麗的女孩,美麗的女孩未婚懷孕了,她的父母非常生氣;就嚴厲的逼問女孩的生父是誰?

女孩因為深怕父母譴責,於是說出了白隱禪師名字。

不明真相的父母聽信女兒讒言,抱著剛生下的嬰兒,扔給白隱禪師並說道:「你這個敗壞佛門清規戒律的假和尚,以前我們沒有看清你的醜惡面目,蒙受你的欺騙。沒想到你竟然作出如此禽獸不如的勾當,這是你的兒子,你拿去吧!」。白隱禪師聽完後,只是說了一句:「喔,是這樣嗎?」,就默默地接過孩子了。

此時的白隱禪師已經名聲掃地,然而他自己並未因此而受到干擾;仍然默默忍受著種種白眼非議;獨自準備孩子所需的一切東西,並細心照料這個幼小的生命。

一年以後,年輕的媽媽良心倍受痛苦的煎熬,她不能再忍受人們對白隱禪師的不公平待遇,終於向父母坦白了一切,說明孩子真正的生父是村外的一個年輕人;她的父母親得知真相後大吃一驚,立即去找白隱禪師,向他表示深深的歉意,誠懇的請求她的寬恕,並將孩子領回。

白隱禪師把孩子送還給他們時,只輕輕的說了一句:「喔,是這樣嗎?」


《入菩薩行論》云:「罪惡莫過瞋,難行莫勝忍,故應以眾理,努力修安忍。」對於佛教徒來說,白隱禪師的安忍境界已經深到不可思議的地步。但對於我來說,第一次的「喔,是這樣嗎?」,聽起來有點懦弱無能的感覺。直到真相大白後,第二次所說的「喔,是這樣嗎?」,真的有重重一巴掌打在我臉上的感覺。不過是這麼一句平淡的話,其展現的力道,還真的是「柔弱勝剛強」哩。

2011年9月4日 星期日

生命的恆沙


水,本是清淨、無染。生命的初始,亦何嘗不是。從一個生命停留於一個身體開始,就好像將水開始注入一個杯子,隨著時間的推移,注入杯子裡的水也就慢慢變多了。

人與非人之間的差異,在於懂得思考,但同時也因為思考而讓每個人存在著太多的相異性。眼睛所見,耳朵所聽,鼻子所聞,舌頭所嚐,身體所感受,絕對每天不同、每人不同、每次不同。


「坐井觀天」、「三人成虎」、「瞎子摸象」的故事,告訴了我們眼見不能為憑、耳聞不能成真、所知並非全貌的道理。很多小朋友小時候很怕黑,是因為他們把原本無害的東西視為妖怪野獸,即便是一件衣服掛在昏暗的角落裡,他都會生起無比的恐懼感。

當你接受了負面的訊息,就像是將一粒沙放進了你的水杯。多年之後,原本清澈的水杯,早已不知累積了多少沙子。直到有一天,你的心緒已無法獲得寧靜時,才赫然發現你的那杯水,正因被攪動而混濁不已。有人建議你,時間是療傷良藥,但其實並不是如此,留下沙子的水杯,不管加注再多的水,沙子依然存在。唯一你能做的,就是讓杯子安靜下來,待沙子沈澱之後,即可再見水的清澈。或許你會問,那裡頭的沙子怎麼辦?如何徹底把它們清乾淨呢?這問題問得好,而答案是永遠不可能清除乾淨。試問,你過去所做過的事,犯過的錯,今天可以抹煞掉它嗎?即便是經過五年、十年之後,過去所發生的事,依然不可能憑空消失,這樣的道理,你就應該可以理解為何無法消除杯子裡的沙了。

而我們也毋需因此而難過,因為身邊周遭的人,乃至大部分的人,都存在著相同的問題。若是如此,你所擔憂的就不再是如何去清除沙子,而是如何讓水杯靜下來,讓沙子上面再次呈現水的清淨與無染。

這很難嗎?可以說是,也可以說不是?於「觀照身體.修復心靈」一書有個例子可分享:

有一個小男孩在沙灘上玩耍。尚未漲潮時,他用沙子堆了一座有護城河的城堡。開始漲潮時,起初的海浪都會剛好流進護城河。小男孩也因此感到自豪且開心。但隨著潮水越漲越高,最終還是把他的城堡給沖毀了,最後留下來的,只剩下擺著臭臉直跺腳的小男孩。

幾公尺外的沙灘上,也有一個小女孩在玩同樣的遊戲。但當她的城堡被沖毀時,掙扎的情緒並沒有維持很久,因為她開始發現了新玩法。每當潮水退去,她就馬上在地上挖洞,當海水再次湧上來,她看著海水如她所料的一一填滿這些坑洞,她就覺得很開心。

生命本是無常,既是無常,又何須執著呢?靜下來看看自己的杯子,面對生命的恆沙,你在乎的是裡頭的沙,亦或清淨無染的水呢?

各種宗教教義,皆不離「與人為善,修福修慧」。你今日做一善行,生命的水杯即會掉入一顆七彩琉璃,累積越多善行,琉璃的數目就越多。日後端視水杯時,見到沙子裡點綴者好多七彩琉璃,就會心生好歡喜。此外,也有另一派人,強調持戒斷惡,讓過往所留下的沙,就此停住,冀望日後所得唯有清淨無染。更甚者,有人既做善行,也恆持戒。言至於此,如此看待人生,「累不累啊」?

水,不因一粒沙,而改其清淨無染的本質。
水,不因一琉璃,而改其清淨無染的本質。
水,不因外相的混濁,而改其清淨無染的本質。

如果你能明瞭水的本質,不管你是看杯子裡的沙,還是杯子裡的水,終究也都是清淨無染的。大家都曾聽過六祖的傳世之句:

「菩提本無樹,明鏡亦非台,本來無一物,何處惹塵埃」。

以古照今,其華不減。聖人前賢有其大智慧,而我凡夫豈能不起效尤?

近日有幸重讀「古今背書方法」,有段與我相應的話:

「余嘗謂讀書有三到:謂心到、眼到、口到,心不在此,則眼不看仔細;心眼既不專一,卻只漫浪誦讀,決不能記,記亦不能久也。三到之法,心到最急,心既到矣,眼口豈不到乎!」

為學,為人,為事之本,存乎一心,若能修習「心如止水」的功夫,則塵土必落,靈台也能獲得清明。

參考:
01:古今背書方法(宋 朱熹 朱子童蒙須知)
02:「觀照身體.修復心靈」。瓊恩.波利森科(Joan Borysenko),出版社:張老師文化

2011年9月1日 星期四

讓我們擠在一起


越來越多美編喜歡用 DIV 來設計樣板,不像我們傳統工程師,都是用 Table 去 layout 畫面。或許在未來新的瀏覽器裡,對 CSS 的支援更強大、更統一之後,以 DIV + CSS 為設計的方式將會越來越普遍。但將來的事,現在說什麼都還算太早,眼下我先搞定如何將兩個 DIV 放在同一列比較重要。

原先我都以為使用 DIV ,就一定會佔用一行的空間。沒想到透過 {float:left;} 的 CSS 定義後,就可以讓好幾個 DIV 擠在一起。

參考一下 HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title></title>
<style>
.oneline
{
float:left;
}

div{
border-width:1px;
border-color:red;
border-style:solid;
border-color: #336699;
padding:1px;
}

</style>
</head>
<body>
<div style="padding-top:30px" class="oneline">元素A</div>
<div class="oneline">元素B</div>
<div style="clear:left;">元素C</div>

</body>
</html>
透過 float:left ,讓元素A、元素B 都擠在同一列。但如果希望這行為不要發生在元素C,則可以透過 clear:left 來結束。

此外,除了使用 float:left 之外,還可以用 display:inline; 來達到擠在同一列的效果,差別在於 display:inline 會有靠下對齊的效果,而  float:left 則是靠上對齊。


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title></title>
<style>
.oneline
{
display:inline;
}

div{
border-width:1px;
border-color:red;
border-style:solid;
border-color: #336699;
padding:1px;
}

</style>
</head>
<body>
<div style="padding-top:30px" class="oneline">元素A</div>
<div class="oneline">元素B</div>
<div style="clear:left;">元素C</div>

</body>
</html>
參考:

1.關於CSS DIV並排的問題
http://www.lslnet.com/linux/f/docs1/i30/big5240138.htm

2.CSS display 屬性用法介紹 display:block 與 display:inline
http://www.webtech.tw/info.php?tid=37

3.Float vs. Inline-Block
http://www.ternstyle.us/blog/float-vs-inline-block

2011年8月19日 星期五

機會



有一個人,有天晚上碰到一個天使,這個天使告訴他說,有大事要發生在他身上了,他有機會得到很大的財富,在社會上獲得卓越的地位,並且娶到一個漂亮的妻子。

這個人終其一生都在等待這個奇蹟的承諾,可是甚麼事也沒發生。這個人窮困地渡過了他的一生,最後孤獨的老死了。

當他上了天堂,他又看到了那個天使,他對天使說:「你說過要給我財富,很高的社會地位和漂亮的妻子的,我等了一輩子,卻甚麼也沒有。」

天使回答他:「我沒說過那種話。我只承諾過要給你機會得到財富,一個受人尊重的社會地位和一個漂亮的妻子,可是你卻讓這些從你身邊溜走了。」

這個人迷惑了,他說:「我不明白你的意思。」

天使回答道:「你記得你曾經有一次想到一個好點子,可是你沒有行動,因為你怕失敗而不敢去嘗試。」

這個人點點頭。天使繼續說:「因為你沒有去行動,這個點子幾年後被給了另外一個人,那個人一點也不害怕地去做了,你可能記得那個人,他就是後來變成全國最有錢的那個人。


還有,你應該還記得,有一次城裡發生了大地震,城裡大半的房子都毀了,好幾千人被困在倒塌的房子裡,你有機會去幫忙拯救那些存活的人,可是你卻怕小偷會趁你不在家的時候,到你家裡去打劫,偷東西,你以這作為藉口,故意忽視那些需要你幫助的人,而只是守著自己的房子。」



這個人不好意思地點點頭。天使說:「那是你的好機會去拯救幾百個人,而那個機構可以使你在城裡得到多大的尊榮和榮耀啊!

天使繼續說:「你記不記得有一個頭髮烏黑的漂亮女子,那個你曾經非常強烈地被吸引的,你從來不曾這麼喜歡過一個女人,之後也沒有再碰到過像她這麼好的女人。

可是你想她不可能會喜歡你,更不可能會答應跟你結婚,你因為害怕被拒絕,就讓她從你身旁溜走了。」


這個人又點點頭,可是這次他流下了眼淚。

天使說:「我的朋友啊!就是她!她本來應是你的妻子,你們會有好幾個漂亮的小孩,而且跟她在一起,你的人生將會有許許多多的快樂。」

我們每天身邊都會圍繞著很多的機會,包括愛的機會。可是我們經常像故事裡的那個人一樣,總是因為害怕而停止了腳步,結果機會就溜走了。

「是的,害怕!」。我們因為害怕被拒絕而不敢跟人們接觸;我們因為害怕被嘲笑而不敢跟人們溝通情感;我們因為害怕失落的痛苦而不敢對別人付出承諾。

不過,我們比故事裡的那個人多了一個優勢。那就是我們還活著,我們可以從現在起抓住那些機會,我們可以開始去創造我們自己的機會。



節錄自:人生的四大秘密

2011年8月10日 星期三

Unabled to start debugging on the web server

嘗試透過 Team Foundation Server 把程式抓下來,於是連上去找到方案檔(*.sln)並點兩下後,輸入對應的本地端路徑,很開心的發現不只有原始碼被下載到本地端,連 IIS 站台也自動都幫我建立好了。設定好起始專案、起始網頁後,執行 F5,接著就變成一連串的哇哩勒...


「Unabled to start debugging on the web server. The web server could not find the requested resource.」這問題還蠻怪的,他說不能 debug 的原因,是找不到要求的資源。可是我看 IIS ,明明就已經建立好了應用程式站台,怎麼會說找不到資源呢?試著從 IIS 上直接瀏覽網頁,竟然都可以正常瀏覽,表示網站上的程式是正確的,那最大的嫌疑人,就是我的 Asp.Net 專案了。這個專案原先是用 VS2005 所開發的專案,但現在則改用 VS2010 來開啟(win 7 , IIS 7 , 64 bits)。於是認真看了一下我的專案:
ASP.Net 所開啟的網站是:http://localhost/xxx
但剛剛瀏覽 IIS 的網站是:http://paladinPC/xxx

納悶著,這有甚麼差別?於是自己試了所有 http://localhost/ 開頭的專案,都會出現找不到網頁的錯誤。



但,要怎麼把 ASP.Net 的專案,由 localhost 改成站台名稱: paladinPC 呢?於是我把矛頭指向 *.sln 檔,用記事本開啟該檔(不是透過 Visual Studio),找到:

Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "xxx", "http://localhost/xxx", "{8B0D200A-B408-4AC1-A0DE-37DFCF35D64F}"

並把裡面的 localhost 改成自己的 PC 名稱 : paladinPC,然後在重新回到 VS2010,它就會問我要不要 Reload ,回答 YES 之後,就會發現自己的 ASP.Net 專案已經變成 http://paladinPC/xxx,也可以正常偵錯使用了。

2011年8月2日 星期二

加框

「老闆,加個框吧!」

雖然在頁面上加個框並不是困難的事,但對不是視覺系科班出身的我來說,著實很不容易啊!剛好看到一段不錯程式,展現的效果也是「平價中有奢華」,就趕快把它寫下來了。

<html>
<body>

<div style='width: 450px; border:#A9A9A9 3px solid ;'>
 <div style='margin: 3px; border: 1px dotted #A9A9A9;'>內容</div>
</div>

</body>
</html>
 

內容

這段程式,是透過兩個 DIV 組合成邊框,內框則是採用:濕滑螺絲級的-小點,點綴而成,不論是個人使用或是商業應用,都能讓你輕鬆有個自己的框。

2011年7月22日 星期五

Boxing vs. Unboxing

我們常講的型態轉型,譬如說:字串轉數字,這...沒什麼嘛~

但如果突然在書上看到 Boxing vs. Unboxing 時,這....

雖然 Box & Unbox 跟型態轉型有點類似,但實際上還是有一點差別。主要的差別在於轉型的對象,如果你將特定型(如 int,string...)轉換成 object ,這過程就叫做 Boxing ,反之,如果將 object 轉換成特定型別,就叫做 Unboxing 。

在 MSDN 說得很清楚,對大家來說,比較像是名詞定義而已。

int i=123;
object o = (object)i; //boxing

int j=(int)o; //unboxing


不管是執行 Box 還是 Unbox 動作,都是要耗費運算資源的。

以下針對有進行 Boxing 與 沒有 Boxing 進行了比較:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace boxtest
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stop = new Stopwatch();

            //啟動計時
            stop.Start();
            List<object> Box = new List<object>();

            //重複 100 萬次
            for (int i = 0; i < 1000000; i++) 
            {
                //進行 Boxing 動作
                Box.Add((object)i);
            }
          
            //停止計時
            stop.Stop();

            //取得耗時數據
            TimeSpan ts = stop.Elapsed;

            //啟動計時
            stop.Reset();
            stop.Start();

            List<int> NoBox = new List<int>();

            //重複 100 萬次
            for (int i = 0; i < 1000000; i++)
            {
                //沒有進行 Boxing
                NoBox.Add(i);
            }
                     

            //停止計時
            stop.Stop();

            //取得耗時數據
            TimeSpan ts2 = stop.Elapsed;


            //列印耗時結果(有 Boxing)
            Console.WriteLine("有Boxing...");
            Console.WriteLine(string.Format("{0:00}:{1:00}:{2:00}:{3:00}",
                ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10));


            //列印耗時結果(沒有 Boxing)
            Console.WriteLine("");
            Console.WriteLine("沒有Boxing...");
            Console.WriteLine(string.Format("{0:00}:{1:00}:{2:00}:{3:00}",
                ts2.Hours, ts2.Minutes, ts2.Seconds, ts2.Milliseconds / 10));
            Console.ReadKey();
        }
    }
}




於是可以明確知道,有進行 Boxing 的操作,會比沒有 Boxing 的增加 7 倍運算資源。

參考網址:Boxing 和 Unboxing (C# 程式設計手冊)

程式的沙漏

田徑場上,為了測試運動員的優秀程度,可以透過碼錶來衡量。那你程式寫得好不好,要用什麼來衡量呢?我想,Bug 只是驗證你程式對不對,但「好不好」,可能還真的要拿出碼錶來量一下。

在 C# 裡,還真的有碼錶類別可使用哩!正巧也叫「Stopwatch」。功能也很簡單,大概常會用到的,應該只有啟動(Start)、暫停(Stop)、清除(Reset) 這三項。

以簡單例子來說明:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;

namespace ElapsedTime
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stop = new Stopwatch();

            //啟動計時
            stop.Start();

            //使用 Thread.Sleep 模擬耗時的程式流程
            Thread.Sleep(10000);

            //停止計時
            stop.Stop();

            //取得耗時數據
            TimeSpan ts = stop.Elapsed;

            //列印耗時結果
            Console.WriteLine(string.Format("{0:00}:{1:00}:{2:00}:{3:00}",
                ts.Hours,ts.Minutes,ts.Seconds,ts.Milliseconds/10));
            Console.ReadKey();
        }
    }
}

日後,如果要比較程式效能時,就可以透過這碼錶取得精確的數據。

參考:Stopwatch 類別

2011年7月14日 星期四

至少要交一個女友

如過要設計個頁面,讓使用者填寫歷任女友姓名,且要判斷至少要填寫一個。這需求很像還蠻簡單的。可以一筆一筆去檢查輸入方塊,只要有值就算通過了。

雖然判斷式一行一行寫不是難事,但卻稍嫌累贅,所以花了些時間想瞭解 jQuery 是否可以處理的更漂亮。於是找到了一個可行的方法,並將他記錄下來!

<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
function CheckNeedOne()
{
   var msg='有值的共有:'+$(".data").filter(function(index){ if($(this).val()=='') return false; return true; }).size();
   if($(".data").filter(function(index){ if($(this).val()=='') return false; return true; }).size()==0)
   { 
 alert(msg+'\n至少要填一項!');
 return false;
   }

   alert(msg);
   return true;
}
</script>
</head>
<body>
<input type="text" id="tbx01" class="data"><br>
<input type="text" id="tbx02" class="data"><br>
<input type="text" id="tbx03" class="data"><br>
<input type="text" id="tbx04" class="data"><br>
<input type="text" id="tbx05" class="data"><br>
<input type="button" value="Send" onclick="return CheckNeedOne();">
</body>
</html>

執行結果:












主要是使用了 jQuery 所提供的 filter(function(index) ) 方法。原先的 $(".data"),讓我取得了5個輸入方塊,再透過 filter( ) 來過濾我所需要的資料。只是這次所要過濾的規則,希望是透過自己所定的規則,判斷輸入方塊是否有值,也就是待會要寫在 function(index) 裡的程式。

在 function(index) 裡,如果目前所檢查的輸入方塊有值,就回傳 true ,反之,則回傳 false。所以就寫成:

if($(this).val()=='') 
  return false; 

return true;

所以,符合 filter(function(index)) 的結果,都是有資料的輸入方塊,最後再透過 .size() 來取得符合的數目,用它來判斷是否大於0,如果沒有的話,就會跳出警告訊息。

$(".data").filter(function(index){ if($(this).val()=='') return false; return true; }).size()
 

希望自己下次再看到這填寫歷任女友的需求時,還會找到更簡潔的作法。

2011年7月13日 星期三

這一定要貼在辦公室門口

員工篇
老闆篇

2011年6月29日 星期三

讓 GridView 的 CommandArgument 傳遞多個參數

一般在使用 GridView 時,如果想要在 RowCommand 事件取得識別資訊,通常都可以事先在 CommandArgument 寫好。但如果需要同時傳入多個參數時,是否也可以達到呢?可以的,不難,慢慢來。

為了測試方便,建立了一個 testData.xml 檔:
<?xml version="1.0" encoding="utf-8" ?>
<data>
  <row id="001" name="paladin"></row>
  <row id="002" name="ltt"></row>  
</data>

接著在 testData.aspx 頁面,使用了 XmlDataSouce 將剛剛的 xml 當作資料來源。



繼續將我的 gridview 完成:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="XmlDataSource1" OnRowCommand="GridView1_RowCommand">
    <Columns>
        <asp:BoundField DataField="id" HeaderText="id" SortExpression="id" />                
        <asp:TemplateField HeaderText="name">
            <ItemTemplate>
                <asp:LinkButton ID="btnDetail" runat="server" CommandName="ViewDetail" CommandArgument='<%#Eval("id")+","+Eval("name") %>'><%#Eval("name") %></asp:LinkButton>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

最後,在 testData.aspx.cs 的 GridView1_RowCommand() 事件,將使用者點選的資料顯示出來:

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "ViewDetail")
    {
        Response.Write(string.Format("Selected ID:{0};Selected Name:{1}", 
            e.CommandArgument.ToString().Split(',')[0].Trim(), 
            e.CommandArgument.ToString().Split(',')[1].Trim()));
    }
}
 

結果如下:

最主要的重點,在於 CommandArgument 的使用方式:

CommandArgument='<%#Eval("id")+","+Eval("name") %>'

先用  '<%# ... %>' 把整個內容包括起來,而兩個參數間,則是透過 "," 來區隔,並以 「+」來串接。

日後不管是要串幾個,都不再是問題了。

此外,透過這方式傳參數,去檢視原始碼,也不會出現 CommandArgument 所指派的內容。
<table cellspacing="0" rules="all" border="1" id="GridView1" style="border-collapse:collapse;">
<tr>
    <th scope="col">id</th><th scope="col">name</th>
</tr><tr>
    <td>001</td><td>
        <a id="GridView1_ctl02_btnDetail" href="javascript:__doPostBack('GridView1$ctl02$btnDetail','')">paladin</a>
    </td>
</tr><tr>
    <td>002</td><td>
        <a id="GridView1_ctl03_btnDetail" href="javascript:__doPostBack('GridView1$ctl03$btnDetail','')">ltt</a>
    </td>
</tr>
</table>

注意到了嗎?HTML 原始碼裡,這個超連結點選後,會觸發 __doPostBack ,但並不會暴露出我們所傳遞多個參數的訊息。

<a id="GridView1_ctl03_btnDetail" href="javascript:__doPostBack('GridView1$ctl03$btnDetail','')">ltt</a>

參考:
01:Passing Multiple value in Command Argument
02:Pass multiple values to Command Argument

2011年6月12日 星期日

做你自己

 
在 cheers 雜誌,介紹了彼得.巴菲特,他正是股神神華倫.巴菲特的兒子。彼得.巴菲特在他「Life Is What You Make It」一書裡,提及父子兩人針對不同投資標的而各自引領風騷。節錄文章中所說得一段精華:

人生要試著什麼都去學。
這年頭所謂的「教育」,往往指的是「就業技能訓練」,這太過狹隘。目標取向的學習只是教育的其中一個面向,假如我們希望自己的人生盡可能多采多姿且令人滿足,那麼我們就應該試著什麼都去學。不要只學用來賺錢的專業本領,還要學我們專業以外的無數其他知識。

停下來審視內心。
「自我內省」嚴然已成為一種遙不可及的奢想,我們總是害怕自己落後別人,因此再也不敢花時間放慢腳步好好思考。然而,好的決定需要花時間。停下來審視自己的內心,絕對不是「浪費」時間,而是對時間的「投資」,它是人生最值得的一種投資。



大巴菲特看投資 小巴菲特看人生

  • 準備是最重要的,諾亞不是下雨之後才開始造方舟。
  • 錢是人創造出來的,但錢不能創造人。
  • 一要接受錯誤的發生;二要坦承錯誤,並勇於面對;三從錯誤中學習,積極過日子。[more]

  • 好運通常以機會的形式出現,是去迎向挑戰、去做困難事的機會,但你必須做好準備,可以接招了,才不會辜負這份好運。
  • 身無分文或近乎身無分文,其實是一種適切的狀態。它在考驗我們變通的能力和幽默感。
  • 倘若因為害怕落後別人,或怕犯下無可挽回的大錯,我們便不院給自己犯錯的空間,那我們一併喪失學習的機會了。

這篇文章,讓我想起以前唸書的時候,學校有教國學常識,不外乎四書五經、孔孟、老莊思想。雖然當下心裡也是會滴咕,這以後又不能當飯吃,唸了作啥?還好聯考會考,所以還是把它念完了。出來工作幾年後,慢慢領悟到,自己目前看到的、遇到的、想要的,其實很多都跟以前所念的國學常識多有關聯,孔孟幾千年前講的話,至今依然受用。這代表了什麼?代表了教育的核心。想想,這歷古彌新的學問,你不好好學,這不是很可惜嗎?反而現在工作上的技能,你只要幾年不碰,肯定退了流行,因為又有更新的技術冒出來了。原來我們一直追求的,是很表面的知識,經不起時間的考驗。

子曰:「始吾於人也,聽其言而信其行;今吾於人也,聽其言而觀其行。」
孔子說,當初我對於別人,是聽到他的話,就相信了他的行為;現在我對於別人,是聽到他的話後,還要觀察他是否是言行一致的人。

以前的孔子,教我們如何去看待週邊朋友所說話,別亂相信別人。如果你有謹記於心,就不容易受騙。但很可惜的,這番美意在我們的考試制度裡,就變成在考:

請問,孔子所說的這句話,是出自哪裡? (A)公冶長篇 (B)xxx (C) ....

出自哪裡很重要嗎?連這種題目都在考,才會讓學生對這門學科產生反感,甚至給他冠上「封建思想」的名號,要把它趕出教材內容。最後,這封建思想在教材範圍裡被排除了,學生們少了背誦的壓力,相對地也失去傳承這千年教育核心的機會。


清代乾隆年間,主編《四庫全書》的著名學者紀曉嵐曾經說過:「世間的道理與事情,都在古人的書中說盡,現在如再著述,仍超不過古人的範圍,又何必再多著述。」這的確是一則名言。 試看今日世界各國學者關於思想學術方面的著作,無不拾古人之牙慧,甚至,強調來說,無不是中國古人已經說過的話。

所以紀曉嵐一生之中,從不著書,只是編書——整理前人的典籍,將中國文化作系統的分類,以便於後來的學者們學習,他自己的著作只有《閱微草堂筆記》一冊而已。 就因為他倚此一態度而為學,自然地讀書非常多,了解得亦較他人深刻而正確。


跌破大家眼鏡的,是國外目前已經開始在流行研讀中國的四書五經、老莊思想,這些我們所摒棄的,別人卻撿起來好好用,嚴然形成我們最不願見到的:「牆內開花、牆外結果」。學校能夠教授國學常識,對學生將來的行為處世上,真的有很大的幫助,若能更進一步地讓課程貼近生活,考試回歸正常而不刁鑽,品格教育,就應由此開始。

參考:
01.2010年11月 Cheers雜誌
02.由老子到孙子--南怀瑾
03.由老子到孫子-中國國學網

2011年6月9日 星期四

C# 的隱含型別

在 C# 語法裡面寫

var v1=38.38 ;
var v2=74.74;
var v_sum=v1+v2;


這樣會不會很奇怪?自己剛遇到時,還一度以為是誰不小心把 javascript 放到 C# 裡了。我的老師常說:「行有不得,反求諸己」,的確,我有好一陣子沒看程式設計的書了。

在 C# 3.0 開始,引進了「隱含型別 (implicitly type )」,編譯器會依據指定給隱含型別變數的初始值自動決定變數的型別。換言之,如果不指定初始值,那隱含型別是否就無法決定正確的型別了?沒錯,使用隱含型別,一定要指定初始值。下面的寫法在編譯時,都會產生錯誤:

var v1;
var v2=null;

使用隱含型別,目前聽到的主要好處有三:


第一:可以少打幾個字。
System.Data.DataSet ds1 = new System.Data.DataSet();
var ds2 = new System.Data.DataSet();
看到了吧!這樣可以避免過度使用你的手指頭...,甚至連 namespace 都可以不用引用了。

第二:配合 LINQ 所產生的查詢結果。
// for linq test
string[] words = {"a111","a222","b111","b222","c111" };
var v_selected_words = 
    from w 
    in words 
    where w[0] == 'b' 
    select w;

foreach (string s in v_selected_words)
{
    Console.WriteLine(s);
}

Console.ReadKey();

如此一來,對習慣使用 LINQ 的人來說,的確可以讓程式整潔一致些。

第三:提供匿名型別(Anonymous Type)。
// for anonymous test
var v_anonymous= new { Name="paladin", Empno="3388"};
Console.WriteLine(v_anonymous.Name);  //show: paladin
Console.WriteLine(v_anonymous.Empno); //show: 3388

Console.ReadKey();

這裡省去了明確宣告類別或變數的動作,允許你直接使用。如果沒有匿名型別,原先的程式寫法,很可能就會如下所示,相較之下,的確省了不少程式。
namespace ConsolVar
{
    class Program
    {
        
        static void Main(string[] args)
        {

            MyClass oM = new MyClass();
            oM.Name = "paladin";
            oM.Empno = "3388";
            Console.WriteLine(oM.Name); //show: paladin
            Console.WriteLine(oM.Empno);//show: 3388           

            Console.ReadKey();
        }        
    }

    public class MyClass
    {
        private string _Name;
        private string _Empno;
        public string Name {
          get { return _Name; } 
          set { _Name = value; } }
        public string Empno { 
          get { return _Empno; } 
          set { _Empno = value; } }
    }
}

瞭解了隱含型別所帶來的好處,但還是要知道他的限制。目前的隱含型別,只能夠用在區域變數而已,而且也不能夠用在類別屬性的宣告裡。例如上面的 MyClass ,下面的寫法則是錯誤的:
public class MyClass
    {
        private string _Name;
        private string _Empno;
        public string Name {
          get { return _Name; } 
          set { _Name = value; } }
        public string Empno { 
          get { return _Empno; } 
          set { _Empno = value; } }
       
        var v = "123"; //錯誤用法
    }

參考:
01:var (C# Reference)
02:Implicitly Typed Local Variables (C# Programming Guide)
03:[C#] 使用 var 關鍵字宣告隱含型別
04:C# 3.0的var隱含型別宣告
05:Anonymous Types
06:C# 3.0 Tutorials: What is Anonymous type?
07:Beginning ASP.NET 3.5 in C# 2008 From Novice to Professional,Second Edition,Matthew MacDonald,Apress