2011年3月31日 星期四

游泳會增加體內的濕氣


我在武國忠醫生的書裡面看到一段話:

誰說游泳一定對心臟有好處呢? 從運動的角度看,游泳能擴張胸部,對胸肺有一些用處,但我們不能僅僅看到這一點啊。 游泳的時候,大量的水濕會通過毛孔滲入體內。 毛孔是肺在體表的開竅,時刻與外界進行氣體交換,當大量的水濕之氣滲入毛孔的時候,肺的工作量就加大了,它要把浸入體內的濕氣轉化成水,並且及時排出體外。


所以,我們游泳,游了一兩個小時上岸後,就去廁所小便。游泳當中一般都沒喝水,這些水從哪兒來? 都是從毛孔滲進來的。 把水濕之氣慢慢轉化成尿液,可想而知人體在游泳的時候做了大量複雜而又艱辛的工作! 但這個工作還不夠,因為,從毛孔到尿道是一段漫長的旅途,水濕能完全排出去嗎? 能保證它在途中沒有滯留嗎? 不能!游泳後,水濕在體內滯留是必然的,所以,游泳增加了體內的濕氣。

這說法,還真的是第一次聽到。我知道可以透過皮膚來呼吸,但是在游泳池裡,皮膚是否可以將水裡的濕氣全部吸收進入體內,形成尿液,真的可就讓我似懂非懂了。如果真的可以這樣,那相傳達摩祖師面壁於少林時,可以多年不吃不喝,若是透過皮膚來吸收空氣裡的水分維繫生命,也不是不可能的事了!



參考:

01:游泳要小心濕氣入侵
02:游泳、洗澡、流汗完必須注意的養身方式
03:為什麼說皮膚也會呼吸呢?

2011年3月30日 星期三

使用 jQuery 添加 HTML 程式片段

最近學到一個透過 jQuery 添加 HTML 程式片段的方法。原來 jQuery 除了讓我們搜尋 HTML DOM 以外,還可以輕易的建立 HTML 。

<html>
<head runat="server">
    <script src="http://code.jquery.com/jquery-1.5.js"></script>
    <script>
        $(function () {
            $("<div>這是我自建的 HTML </div>").appendTo($("#sp"));
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <span id="sp"></span>
    </div>
    </form>
</body>
</html>

以上面的程式為例:使用 $("<div>這是我自建的 HTML </div>"),建立了一個 <div> 物件,並將這物件指定擺放到 <span id="sp"></span>。


甚至更進一步,可以在我們自建的 HTML 裡,事先設定 jQuery 的變化。舉裡來說:

<html>
<head runat="server">
    <title></title>
    <script src="http://code.jquery.com/jquery-1.5.js"></script>
    <script>
        $(function () {
            $("<div>這是我自建的 HTML </div><div class='cs1'>指定顏色一</div><div class='cs2'>指定顏色二</div>").filter(".cs1").css("color","red").end().filter(".cs2").css("color","green").end().appendTo($("#sp"));
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <span id="sp"></span>
    </div>
    </form>
</body>
</html>

在自建的 HTML 中,針對
<div>這是我自建的 HTML </div>
<div class='cs1'>指定顏色一</div>
<div class='cs2'>指定顏色二</div>

分別針對 class=cs1 與 class=cs2 設定了 red 與 green 顏色,最後再塞到 <span> 裡。
.filter(".cs1").css("color","red").end().filter(".cs2").css("color","green").end().appendTo($("#sp"))


在實作的過程中,自己不小心將自建的 HTML 寫成:

原來,我把它寫成巢狀式(nested)的 <div> 了。它結果變成:

納悶的是,即便我寫成了巢狀式的語法,那又有什麼關係?可它就偏偏不如我願。後來發現了自己疏忽的地方,在於沒搞清出 jQuery 的 .filter() 與 .find() 的區別。這裡我很讚賞【钱途无梁】的文章「jQuery基础---filter()和find()」,裡面提的範例簡單明瞭。而我簡單的分別心得則是:

filter() :是找自己的兒子輩(就只到兒子輩而已)。
find()  :是找自己的孫子輩(不含兒子輩,但含曾孫、玄孫...)

所以,即便是面臨巢狀的情形,也不怕外漏了。

<html>
<head runat="server">
    <title></title>
    <script src="http://code.jquery.com/jquery-1.5.js"></script>
    <script>
        $(function () {
            $("<div>這是我自建的 HTML </div><div class='cs1'>指定顏色一<div class='cs2'>指定顏色二</div></div>").filter(".cs1").css("color", "red").end().filter(".cs2").css("color", "green").end().find(".cs1").css("color","red").end().find(".cs2").css("color","green").end().appendTo($("#sp"));
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <span id="sp"></span>
    </div>
    </form>
</body>
</html>

節錄【钱途无梁】的範例:

    <div class="css">
         <p class="rain">測試1</p>
    </div>
    <div class="rain">
         <p>測試2</p>
    </div>

如果執行:
    var $find = $("div").find(".rain");
    alert($find.html());

則結果是:

如果執行:
    var $filter = $("div").filter(".rain");
    alert($filter.html());

結果則是:






參考 01. jQuery基础---filter()和find()

2011年3月25日 星期五

關於 SQL 2008 的 Table Value Parameters (TVP)

以往為了將網頁上的多筆資料新增到資料庫,都會將這些資料透過分隔符號組成一個很長的字串或是用 xml 方式來解決(ref:05)。直到 SQL 2008 問世後,開始提供了一個「使用者定義資料表類型」,使得以前揮汗如雨的情況有了改善。簡單的說,從 SQL 2008 開始,您傳給 Store Procedure 或 function 的參數,開始支援「資料表」了。但這裡所指的資料表,並非隨便亂塞一個就行,反而需要事前先在資料庫裡定義資料表類型,日後才能使用。所以要使用 Table Value Parameters(TVP),首先必須先去定義你自己的資料表類型。



圖1
新增自己的資料表類型,可以參考(圖1),找到「使用者定義資料表類型」,並點選「新增使用者定義表類型」。

-- ================================
-- Create User-defined Table Type
-- ================================
USE projmng
GO

-- Create the data type
CREATE TYPE dbo.BKTable AS TABLE 
(
 TID int NOT NULL, 
 TName nvarchar(50) NULL,  
    PRIMARY KEY (TID)
)
GO


在目前範例中,我建立了一個名為 BKTable 的自訂資料表類型,有兩個欄位 TID 與 TName ,其中的 TID 是 PKey。
declare @TB BKTable
insert into @TB values
(1,'Paladin'),(2,'Hugo')

select * from @TB
建立完我們自訂的資料表類型後,我好奇地先宣告了一個 BKTable 的變數 @TB 。把它視為是一個 Table ,所以試著把些資料新增進去,再顯示 @TB 的結果,就如(圖2)所示,跟以前使用資料表的方式幾乎一樣。



圖2

為了方便說明,建立了一個實體資料表 TB ,以便待會測試時使用。

/*-------------------------------------
   create DataTable: TB
  -------------------------------------*/
CREATE TABLE [dbo].[TB](
 [tID] [int] IDENTITY(1,1) NOT NULL,
 [tName] [nvarchar](50) NULL,
 [tKeyin] [nvarchar](20) NULL,
 CONSTRAINT [PK_TB] PRIMARY KEY CLUSTERED 
(
 [tID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

接著建立一個 Store Procedure : pr_tb_insert ,用來解釋如何使用 TVP 當作參數傳入 Store Procedure。在下面這段程式裡,傳入參數 @tb 正是我們自訂資料表類型 (BKTable),唯一特別的地方,是要在參數後方加註 READONLY ,也就是說,針對這個參數 @tb 所指定的資料表內容,就不可以再進行 Insert , Update , Delete 的動作,但你可以使用 Select 或 與其他資料表進行 join (ref:01)。

/*-------------------------------------
   create Procedure: pr_tb_insert
  -------------------------------------*/
CREATE PROCEDURE [dbo].[pr_tb_insert] 
 -- Add the parameters for the stored procedure here
 @tb BKTable READONLY,@keyin nvarchar(50)
AS
BEGIN
 -- SET NOCOUNT ON added to prevent extra result sets from
 -- interfering with SELECT statements.
 SET NOCOUNT ON;

    -- Insert statements for procedure here
 insert into TB 
 select TName,@keyin from @tb
END
GO

以開發工具 VS2010 為例,先將自己的資料存到 Asp.Net 的 DataTable,後續要執行新增的動作時所要注意的地方,是SqlParameter 的資料型別需要設定為「SqlDbType.Structured」,而其他部份則跟你一般在寫的語法沒多大差別。執行完後,就可以看到因呼叫 Store Procedure :pr_tb_insert 而正確的將資料塞進資料表 TB 的結果。

DataTable dt = new DataTable();
DataColumn column = null;

// add column1
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "id";
dt.Columns.Add(column);

// add column2
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Name";
dt.Columns.Add(column);

DataRow dr = null;
// add row1
dr = dt.NewRow();
dr["id"] = "1";
dr["Name"] = "paladin lee";
dt.Rows.Add(dr);

// add row2
dr = dt.NewRow();
dr["id"] = "2";
dr["Name"] = "ken pen";
dt.Rows.Add(dr);

// add row3
dr = dt.NewRow();
dr["id"] = "3";
dr["Name"] = "lillian cheng";
dt.Rows.Add(dr);

Session["MyDT"] = dt;

SqlConnection con;
// 設定連線資訊
string conStr = System.Configuration.ConfigurationManager.ConnectionStrings["projmngConnectionString"].ConnectionString; 
con = new SqlConnection(conStr);
con.Open();
using (con)
{
    // Configure the SqlCommand and SqlParameter.
    SqlCommand sqlCmd = new SqlCommand("pr_tb_insert", con);
    sqlCmd.CommandType = CommandType.StoredProcedure;
    SqlParameter tvpParam = sqlCmd.Parameters.AddWithValue("@tb", dt); //設定 TVP
    tvpParam.SqlDbType = SqlDbType.Structured; //宣告傳入參數的型別是 TVP

    sqlCmd.Parameters.AddWithValue("@keyin", "jj");
    sqlCmd.ExecuteNonQuery();
}
con.Close();

測試的過程中,發現如果你習慣使用 SqlDataSource 來操作資料庫的動作,在處理 TVP 時,會因為找不到可以與參數型別 SqlDbType.Structured 相對應的設定而苦惱。這時可以透過 SessionParameter 指定 SessionField 來處理(ref 06)。它的原理,是將 DataTable 的資料存到 Session ,而後在 SqlDataSource 去指定那個 Session 來當參數。

程式參考:

.aspx
<asp:SqlDataSource ID="ds_insert" runat="server" 
        ConnectionString="<%$ ConnectionStrings:projmngConnectionString %>" 
        SelectCommand="pr_tb_insert" SelectCommandType="StoredProcedure">
        <SelectParameters>
            <asp:SessionParameter ConvertEmptyStringToNull="False" Name="tb" 
                SessionField="MyDT"  />
            <asp:Parameter ConvertEmptyStringToNull="False" Name="keyin" Type="String" />
        </SelectParameters>
    </asp:SqlDataSource>

.aspx.cs
DataTable dt = new DataTable();
DataColumn column = null;

// add column1
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "id";
dt.Columns.Add(column);

// add column2
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Name";
dt.Columns.Add(column);

DataRow dr = null;
// add row1
dr = dt.NewRow();
dr["id"] = "1";
dr["Name"] = "paladin lee";
dt.Rows.Add(dr);

// add row2
dr = dt.NewRow();
dr["id"] = "2";
dr["Name"] = "ken pen";
dt.Rows.Add(dr);

// add row3
dr = dt.NewRow();
dr["id"] = "3";
dr["Name"] = "lillian cheng";
dt.Rows.Add(dr);

Session["MyDT"]=dt;

ds_insert.SelectParameters["keyin"].DefaultValue = "jason";
ds_insert.Select(new DataSourceSelectArguments());

補充(20110408):
在一個專案上實際使用 TVP 的功能,而且也採用 SQLDataSource,因為我的資料表非常的大,沒想到發生了以下錯誤:

The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 1 ("@tb"): Data type 0x62 (sql_variant) has an invalid type for type-specific metadata.


目前對於這問題,還是沒有明確的解決方式,但放棄使用 SQLDataSource ,卻是眼下可行的方式。


ref 01:Table Valued Parameters New In SQL Server 2008 T-SQL Improvements
ref 02:SQL Server 2008: Table Valued Parameters
ref 03:Sql2008中使用DataTable作为存储过程的参数
ref 04:Table Value Parameters in SQL Server 2008 and .NET (C#)
ref 05:Sales Order Workshop - Articles at SQLServerCentral.com
ref 06:How to set up ASP.NET SQL Datasource to accept TVP

2011年3月23日 星期三

T-SQL 取得資料表的 schema

如果想透過 T-SQL 來取得資料庫中的某個資料表的 schema,可以透過以下語法:

--宣告所要查詢的資料表名稱
declare @tbName nvarchar(200)
set @tbName='close_base'

Select a.colid, a.name,
 c.name + '(' + Convert(varchar(4), (Case When a.xtype In (99, 231, 239) Then a.length / 2 Else a.length End)) + ')' col_type, 
 (Case When b.pk_name Is Not Null Then 'PK' Else 
  (Case When a.isnullable = 0 Then 'NN' Else 'N' End) End) col_status,
 IsNull(e.text, '') col_default
From sysobjects main
Inner Join syscolumns a
 On main.id = a.id
Left Join (
  Select a.id, c.name pk_name
  From sysindexes a
  Inner Join sysindexkeys b
   On a.id = b.id And a.indid = b.indid
  Inner Join syscolumns c
   On a.id = c.id And b.colid = c.colid
  Where a.status & 2048 = 2048) b
 On a.id = b.id And a.name = b.pk_name
Inner Join systypes c
 On a.xtype = c.xtype And c.status = 0 
 --and c.name<>'image' --可在此過濾欄位格式
Left Join sys.extended_properties d
 On a.id = d.major_id And a.colid = d.minor_id 
 And d.name = 'chnName'
Left Join dbo.syscomments e
 On a.cdefault = e.id
Where main.name = @tbName
order by a.colid

就可以得到所要的 schema 內容了。

2011年3月14日 星期一

jQuery .end()

在 jQuery 的語法中,有提供一個 .end() 的方法,最近才開始有使用到,覺得其重要性其實蠻高的,所以稍微紀錄一下自己的心得。

jQuery 的陳述句,具有串鏈(chaining)的特性,譬如說:

$("p").find("span").find(".read")

這語法,是先找出目前頁面上所有 <p> 的標籤,假設有10個,
接著在從目前的篩選結果中找出有<span>的標籤,可能只有5個,
最後,在從這剩下的結果中找出 class=read的項目,可能只剩下2個了。
透過串鏈的好處,可以讓我們一層一層去篩選我們想要的結果,但有沒有想過,這一串 jQuery 語法,雖然可以幫我找到想要的結果,但如果我想同時去處理兩種以上的結果時,該怎麼辦呢?從上面的例子中,我最後是要找從<span>中找出 class name 等於 read 的項目,但如果我也想同時在一個 jQuery 中處理 class name 等於 write 的項目時,可行嗎?

在 jQuery 裡,為了解決上述的疑問,他提供了 .end() 的語法,其意義就好比告訴人家,從這裡開始,回到上一層篩選結果。我們每執行一次具有破壞篩選結果的語法時,就會影響到存放目前篩選結果的堆疊。譬如上述例子,執行了 $("p"),存放在結果堆疊裡一共有10個值,但當你接著執行 .find("span") 之後,堆疊結果加進了第二次的5個查詢結果。最後一次執行了 .find("read"),則堆疊中加入了2個查詢結果。

當你執行了 .end(),則會從結果堆疊中 pop 最上層的結果,也就是把第三次的篩選結果移除,而接著要處理的項目就是 $("p").find("span") 的篩選結果了。所以,如果你想要進一步找出 class name 等於 write 的項目時,則只要在 .end()之後,加上 .find(".write")。
另外一個值得注意的是,由上圖可知,你執行一次 .end() 就會將結果堆疊 pop 一次,那是否可以執行 2 次呢?也就是,可以執行 .end().end() 嗎?可以的,由上圖可知,若您連續兩次的 .end().end() ,就會連續 pop 兩次,則結果堆疊就會只剩下  $("p") 。那如果連續 .end().end().end() 三次呢?看來你的劣根性跟我一樣,如果這樣玩的話,jQuery 就會....回傳空值了,而你的結果堆疊也就被清空了。

上面所提及的「具有破壞篩選結果的語法」,在 jQuery 說明文件中,列舉了以下語法都是具有破壞篩選結果的語法:
 add(),andSelf(),children(),closes(),filter(),find(),map(),next(),nextAll(),not(),parent(),parents(),prev(),prevAll(),siblings(),slice(),clone(),appendTo(),prependTo(),insertBefore(),insertAfter(),replaceAll()

可能會覺得奇怪,為何一定要這麼麻煩,將兩個查詢結果全部寫在一句 jQuery,分兩次寫不可以嗎?原先上面的查詢語法是:

$("p").find("span").find(".read").end().find("write")

難道不能寫成:

$("p").find("span").find(".read")
$("p").find("span").find(".write")

這樣嗎?

這種寫法,我完全同意,但當我讀了 finalevil 的一篇 [jQuery]jQuery Chaining(鏈式語法) 文章後,深深覺得 .end() 的價值排名提昇了不少。因為瀏覽器會將網頁分析後產生 Dom Tree,而 jQuery 的查詢就是針對這個 Dom Tree 去搜尋。只要是 Tree 的搜尋,都是會花時間的。如果一次可以尋訪完,你分了好幾次,當你的 jQuery 查詢次數變多時,或是 Dom Tree 是個非常大的一棵樹,想必您對效能的體會應該會更高些。以上心得,與有緣人共勉之~

參考連結:
01.A Complete Guide To jQuery – Learning The Basics
02.[jQuery]jQuery Chaining(鏈式語法)

2011年3月7日 星期一

使用 jQuery 讓 DropDownList 的值動態依據條件來顯示

有個需求,希望 DropDownList 裡面的值,可以依據 check box 的條件,動態去更新。以下圖來說,當 check box 條件沒有勾選時,DropDownList 的值一共有:請選擇、A、B、C 四個選項。但當 check box 條件勾選了 c2,c3 時,則 DropDownList 的值只剩下:請選擇、B、C 三個選項。用 jQuery 來練習一下...

這次,我用到了 jQuery 的 remove() 與 append() 兩個方法。每當 check box 觸發了 click 事件,我就先用 remove() 清除掉目前 DropDownList 裡的所有值,並依據 check box 的勾選條件來將 DropDownList 裡的選項一一透過 append() 方法來加入。

<!DOCTYPE html>
<html>
<head>
  <script src="http://code.jquery.com/jquery-1.5.js"></script>
  <script>

//設定結果清單
function SettingCheckItems()
{ 
 //移除所有結果
 $("#sel > option").remove();

 //先新增第一個結果:「請選擇」
 $("#sel").append('');

 //如果條件有勾選 c1,則結果新增一個 c1
 if($("input[type=checkbox][name=c1]:checked").length>0)
  $("#sel").append('');

 //如果條件有勾選 c2,則結果新增一個 c2
 if($("input[type=checkbox][name=c2]:checked").length>0)
  $("#sel").append('');

 //如果條件有勾選 c3,則結果新增一個 c3
 if($("input[type=checkbox][name=c3]:checked").length>0)
  $("#sel").append('');

 //如果都沒有勾選任何條件,則將所有結果都列出
 if($("input[type=checkbox]:checked").length==0)
 {
  $("#sel").append('');
  $("#sel").append('');
  $("#sel").append('');
 } 

}


  $(function(){
 //畫面初始時,先執行結果的設定
 SettingCheckItems();

 //如果條件的 checkbox 有被異動,則設定結果清單
 $("input[type=checkbox]").click(function(){ 
  SettingCheckItems();
        });
  });

  </script>
</head>
<body>

  條件:
  <input type="checkbox" name="c1" value="c1">c1
  <input type="checkbox" name="c2" value="c2">c2
  <input type="checkbox" name="c3" value="c3">c3   結果:
  <select id="sel" >
  <option value="" >請選擇</option>  
  </select>

</body>
</html>

如果不打算用 ASP.Net 來撰寫,程式到此應該算是完成了。只是當我用 ASP.Net 改寫時,遇到了沒有預期的錯誤訊息。我使用了 <asp:CheckBoxList /> <asp:DropDownList /> ,並加上一個會觸發 postback 的 Button 來顯示目前所挑選的結果值,沒想到卻出現了一個錯誤訊息:

 Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

原來 asp.net 在每一次的 postback 會去呼叫  EventValidation,而  EventValidation 則是將每一次 Render 畫面時的控制項與值都會記錄下來,並且去與上一次比較是否有所不同。這個用意,是為了提高網站的安全性,避免被攻擊的疑慮。但由於我透過 DOM 的操作,去增加或減少了頁面的 DOM 項目,當然與 EventValidation 的設計有所違背,所以會出現上面的錯誤訊息。

而微軟似乎也沒這麼霸道,提供了兩個選擇,第一,就是關掉 EventValidation 的驗證。但缺點就是會降低網頁的安全性。第二,使用 ClientScriptManager 去寫RegisterForEventValidation 方法,這似乎是個解決方法,但...好麻煩。 最簡單的方法,就是,不要用。是指不要用 <asp:DropDownList />,而是改用 <select id="sel" runat="server> 的方式。日後要抓下拉清單所挑選的值時,就使用 Request.Form["sel"] 。

改完後的 ASP.Net 版如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm4.aspx.cs" Inherits="WebTest.WebForm4" %>

<!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 runat="server">
    <title></title>
    <script src="http://code.jquery.com/jquery-1.5.js"></script>
    <script>
        //設定結果清單
        function SettingCheckItems() {
            alert('t');
            //移除所有結果
            $("select[id*=sel] > option").remove();

            //先新增第一個結果:「請選擇」
            $("select[id*=sel]").append('');

            //如果條件有勾選 c1,則結果新增一個 c1
            if ($("input[type=checkbox][value=c1]:checked").length > 0)
                $("select[id*=sel]").append('');

            //如果條件有勾選 c2,則結果新增一個 c2
            if ($("input[type=checkbox][value=c2]:checked").length > 0)
                $("select[id*=sel]").append('');

            //如果條件有勾選 c3,則結果新增一個 c3
            if ($("input[type=checkbox][value=c3]:checked").length > 0)
                $("select[id*=sel]").append('');

            //如果都沒有勾選任何條件,則將所有結果都列出
            if ($("input[type=checkbox]:checked").length == 0) {
                $("select[id*=sel]").append('');
                $("select[id*=sel]").append('');
                $("select[id*=sel]").append('');
            }

        }

        $(function () {
            //畫面初始時,先執行結果的設定
            SettingCheckItems();

            //如果條件的 checkbox 有被異動,則設定結果清單
            $("input[type=checkbox]").click(function () {
                SettingCheckItems();
            });
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    條件:
        <asp:CheckBoxList ID="cb" runat="server" RepeatDirection="Horizontal" 
            RepeatLayout="Flow">
            <asp:ListItem>c1</asp:ListItem>
            <asp:ListItem>c2</asp:ListItem>
            <asp:ListItem>c3</asp:ListItem>
        </asp:CheckBoxList>
    
      結果:
    <select id="sel" runat="server"></select>
    
    
     
        <asp:Button ID="btnCommit" runat="server" onclick="btnCommit_Click" 
            Text="Commit" />
    
    </div>
    </form>
</body>
</html>


後記:今天在查 jQuery 文件時,發現他的版本已經到 1.5.1 了,新增了許多好玩的地方,有空可以上去瞧瞧囉。

參考:getting exception if the dropdowns are binded with DHTML in the grid