2012年2月4日 星期六

淺析 ASP.NET Form Submit Keypress 事件 by Enter key

老一輩程式設計師都知道,以前在DOS下寫資料庫 AP,在畫面下按Enter鍵跳下一個欄位是預設再平常不過的事,但到了Windows AP下這功能是要自己在 Form.OnKeyPress事件寫處理指令,可是,到了ASP.NET WEB AP下這功能卻又成了預設功能,挺有趣。

ASP.NET Form Submit Keypress 事件 by Enter key其實說到底並不是ASP.NET 的程式設計問題,卻是關於Html Form 中的Submit 按鈕如何運作問題。


ASP.NET Form Submit Keypress 事件 by Enter key測試一:
當你的游標焦點進入某個表單控制項的時候,會啟動該表單中第一個(依Form 上控制項佈局,從左到右,從上至下算起) type="submit" 的按鈕(假如有),等待回應鍵盤及滑鼠的 Keypress 事件,以Submit該Form。
你可以測試一下以下程式碼:
   1. ﹤form action=""﹥
   2. ﹤input type="text" /﹥
   3. ﹤input type="submit" value="submit" /﹥
   4. ﹤/form﹥
   5. ﹤form action=""﹥
   6. ﹤input type="text" /﹥
   7. ﹤input type="button" value="submit" /﹥
   8. ﹤/form﹥


ASP.NET Form Submit Keypress 事件 by Enter key測試二:
在 ASP.NET 2.0 中的 Button 控制項,預設轉換成 Html 為 ﹤input type="submit"﹥,此時不一定要在 Form 的屬性宣告 submit 事件,因為,submit 型態按鈕就是用來提交Form ,在 ASP.NET 1.x時是轉換成 ﹤input type="button" onclick="_doPostBack(...)" /﹥,此普通 button 就不具備 submit 的上述預設提交行為。


ASP.NET Form Submit Keypress 事件 by Enter key測試三:
依上述,若想要禁用此項預設行為有二種方法。

(1)設置 Form 控制項的 DefualtButton 為你希望回應 Enter 的真正按鈕:
   1. ﹤form id="form1"
   2.
   3. runat="server"
   4.
   5. defaultbutton="Button1"﹥

◎注意 DefaultButton = ﹤ ﹤TargetButton.ID﹥﹥,因此這對複合控制項中,比如Login樣版的 Button 可能無效。
◎也可用程式動態指定 this.Form.DefaultButton = "ContentPlaceHolder1$btsubmit";
值得注意的是,如果用了Master Page,那麼要在按鈕ID前加上 Master 的ID:ContentPlaceHolderID和一個金錢符號($)。
◎例如:
‧在Master Page內用:
   1. protected void Page_Load(object sender, EventArgs e)
   2. {
   3.   this.Form.DefaultButton = "ctl00$ContentPlaceHolder1$Login2$LoginButton";
   4. }
‧在Content Page內用:
   1. protected void Page_Load(object sender, EventArgs e)
   2. {
   3.   this.Page.Form.DefaultButton = "ctl00$ContentPlaceHolder1$Login2$LoginButton";
   4. }
‧在一般(未使用Master Page)情況頁面內:
   1. protected void Page_Load(object sender, EventArgs e)
   2. {
   3.   this.Form.DefaultButton = "LoginButton ";
   4. }
‧在使用者自定控制項(.ascx)內:
   1.請先在引用該控制項的表單外部加一個 Panel 包住,
     <asp:Panel ID="Panel1" runat="server">
        .....//使用者自定控制項的內容
     </asp:Panel>
   2.然後再指定 Panel1.DefaultButton = "btsubmit";


(2)修改 Button 呈現方式 UseSubmitBehavior="false":
   1. ﹤asp:Button ID="Button1"
   2.
   3. runat="server" Text="Button"
   4.
   5. onclick="Button1_Click"
   6.
   7. UseSubmitBehavior="false" /﹥

◎個人建議採用(2)作法,簡單易記,效果明確。


另外,可以使用控制焦點的方式,過濾(擋掉) Enter 鍵按下的處理,做法是:
(1)記錄下需要設定過濾的焦點控制項ID,若不知可用獲取當前頁面焦點所在控制項的ID方法:
document.ActiveElement

(2)以ASP.NET Form上在TextBox1中輸入內容後,按下Enter鍵後,就執行Button1的click方法範例下,我們可在Page_Load事件方法中動態指定 TextBox1的屬性,依下寫入:
   1. TextBox1.Attributes.Add("onkeydown",
   2.
   3. "if(event.which || event.keyCode){
   4.
   5. if ((event.which == 13) || (event.keyCode == 13)) {
   6.
   7. document.getElementById('"+
   8.
   9. Button1.UniqueID+"').click();return false;}}
   10.
   11. else {return true}; ");

◎以上作法其實是針對 TextBox1的onKeydown 事件(或改成 Keypress 事件亦可)內,若按下的是 Enter 鍵時不執行下去,但若按下的是滑鼠左鍵,則執行下去。只能針對特定 TextBox 指定,萬一 Form 上有10個 TextBox 則要用 foreach 逐個指定。


參考資料來源:
1.浅析ASP.NET回车提交事件(转)
http://www.cnblogs.com/jiajiayuan/archive/2011/08/26/2154596.html

2. HtmlForm.DefaultButton 屬性
http://msdn.microsoft.com/zh-tw/library/system.web.ui.htmlcontrols.htmlform.defaultbutton(v=vs.80).aspx

3.Master page button event Overloading by content page button event when enter key is pressed
http://stackoverflow.com/questions/4303009/master-page-button-event-overloading-by-content-page-button-event-when-enter-key

4.ASP.NET 2.0 - Enter Key - Default Submit Button
http://geekswithblogs.net/ranganh/archive/2006/04/12/74951.aspx

5.如何讓使用MasterPage啟用 DefaultButton 屬性
http://www.wretch.cc/blog/bigdstut/14296848

6.Setting the default Button for a TextBox in ASP.NET
http://weblogs.asp.net/rajbk/archive/2003/12/11/setting-the-default-button-for-a-textbox-in-asp-net.aspx


---
Welly Lin

沒有留言:

張貼留言