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.由老子到孫子-中國國學網