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