分享內容(
16人
程式碼下載:ASP.NET Server Control - Day29.rar
一、DropDownList 的成員 Value 值相同產生的問題
我們先寫個測試程式來描述問題,在頁面上放置一個 DropDownList 控制項,設定 AutoPostBack=True,並加入四個 ListItem,其中 "王五" 及 "陳六" 二個 ListItem 的 Value 值相同。
在 DropDownList 的 SelectedIndexChanged 事件,輸出 DropDownList 的 SelectedIndex 及 SelectedValue 屬性值。
執行程式,在 DropDownList 選取 "李四" 這個選項時,會正常顯示該成員的 SelectedIndex 及 SelectedValue 屬性值。

接下來選取 "陳六" 這個選項時,竟然發生奇怪的現象,DorpDownList 竟然顯示相同 Value 值的 "王五" 這個成員的 SelectedIndex 及 SelectedValue 屬性值。


二、問題發生的原因
我們先看一下 DropDownList 輸出到用戶端的 HTML 原始碼。
DropDownList 是呼叫 __doPostBack 函式,只傳入 eventTarget參數 (對應到 __EVENTTARGET 這個 HiddenField) 為 DropDownList 的 ClientID;當 PostBack 回伺服端時,在 DropDownList 的 LoadPostData 方法中,會取得用戶端選取的 SelectedValue 值,並去尋找對應的成員的 SelectedIndex 值。可是問題來了,因為 "王五" 與 "陳六" 的 Value 是相同的值,當在尋找符合 Value 值的成員時,前面的選項 "王五" 會先符合條件而傳回該 Index 值,所以先造成取得錯誤的 SelectedIndex 。
三、修改 DropDownList 控制項來解決問題
要解決這個問題最好的方式就是直接修改 DropDownList 控制項,自行處理前端呼叫 __doPostBack 的動作,將用戶端 DropDownList 選擇 SelectedIndex 一併傳回伺服端。所以我們繼承 DropDownList 命名為 TBDropDownList,覆寫 AddAttributesToRender 來自行輸出 PostBack 的用戶端指令碼,我們會用一個變數記錄 AutoPostBack 屬性,並強制將 AutoPostBack 屬性值設為 False,這是為了不要 MyBase 產生 PostBack 的指令碼;然後再自行輸出 AutoPostBack 用戶端指令碼,其中 __doPostBack 的 eventArgument 參數 (對應到 __EVENTARGUMENT 這個 HiddenField) 傳入 this.selectedIndex。
在頁面上放置一個 TBDropDownList 控制項,設定與上述案例相同的成員清單。
執行程式查看 TBDropDownList 控制項的 HTML 原始碼,呼叫 __doPostBack 函式的參數已經被修改,eventArgument 參數會傳入該控制項的 selectedIndex。
[超過字數限制,下一篇接續本文]
一、DropDownList 的成員 Value 值相同產生的問題
我們先寫個測試程式來描述問題,在頁面上放置一個 DropDownList 控制項,設定 AutoPostBack=True,並加入四個 ListItem,其中 "王五" 及 "陳六" 二個 ListItem 的 Value 值相同。
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True">
<asp:ListItem Value="0">張三</asp:ListItem>
<asp:ListItem Value="1">李四</asp:ListItem>
<asp:ListItem Value="2">王五</asp:ListItem>
<asp:ListItem Value="2">陳六</asp:ListItem>
</asp:DropDownList>
在 DropDownList 的 SelectedIndexChanged 事件,輸出 DropDownList 的 SelectedIndex 及 SelectedValue 屬性值。
Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1.SelectedIndexChanged
Dim sText As String
sText = String.Format("DropDownList: Index={0} Value={1}", DropDownList1.SelectedIndex, DropDownList1.SelectedValue)
Me.Response.Write(sText)
End Sub
執行程式,在 DropDownList 選取 "李四" 這個選項時,會正常顯示該成員的 SelectedIndex 及 SelectedValue 屬性值。
接下來選取 "陳六" 這個選項時,竟然發生奇怪的現象,DorpDownList 竟然顯示相同 Value 值的 "王五" 這個成員的 SelectedIndex 及 SelectedValue 屬性值。
二、問題發生的原因
我們先看一下 DropDownList 輸出到用戶端的 HTML 原始碼。
<select name="DropDownList1" onchange="javascript:setTimeout('__doPostBack(\'DropDownList1\',\'\')', 0)" id="DropDownList1">
<option selected="selected" value="0">張三</option>
<option value="1">李四</option>
<option value="2">王五</option>
<option value="2">陳六</option>
</select>
DropDownList 是呼叫 __doPostBack 函式,只傳入 eventTarget參數 (對應到 __EVENTTARGET 這個 HiddenField) 為 DropDownList 的 ClientID;當 PostBack 回伺服端時,在 DropDownList 的 LoadPostData 方法中,會取得用戶端選取的 SelectedValue 值,並去尋找對應的成員的 SelectedIndex 值。可是問題來了,因為 "王五" 與 "陳六" 的 Value 是相同的值,當在尋找符合 Value 值的成員時,前面的選項 "王五" 會先符合條件而傳回該 Index 值,所以先造成取得錯誤的 SelectedIndex 。
Protected Overridable Function LoadPostData(ByVal postDataKey As String, ByVal postCollection As NameValueCollection) As Boolean
Dim values As String() = postCollection.GetValues(postDataKey)
Me.EnsureDataBound
If (Not values Is Nothing) Then
MyBase.ValidateEvent(postDataKey, values(0))
Dim selectedIndex As Integer = Me.Items.FindByValueInternal(values(0), False)
If (Me.SelectedIndex <> selectedIndex) Then
MyBase.SetPostDataSelection(selectedIndex)
Return True
End If
End If
Return False
End Function
三、修改 DropDownList 控制項來解決問題
要解決這個問題最好的方式就是直接修改 DropDownList 控制項,自行處理前端呼叫 __doPostBack 的動作,將用戶端 DropDownList 選擇 SelectedIndex 一併傳回伺服端。所以我們繼承 DropDownList 命名為 TBDropDownList,覆寫 AddAttributesToRender 來自行輸出 PostBack 的用戶端指令碼,我們會用一個變數記錄 AutoPostBack 屬性,並強制將 AutoPostBack 屬性值設為 False,這是為了不要 MyBase 產生 PostBack 的指令碼;然後再自行輸出 AutoPostBack 用戶端指令碼,其中 __doPostBack 的 eventArgument 參數 (對應到 __EVENTARGUMENT 這個 HiddenField) 傳入 this.selectedIndex。
Protected Overrides Sub AddAttributesToRender(ByVal writer As HtmlTextWriter)
Dim bAutoPostBack As Boolean
Dim sScript As String
'記錄 AutoPostBack 值,並將 AutoPostBack 設為 False,不要讓 MyBase 產生 PostBack 的指令碼
bAutoPostBack = Me.AutoPostBack
Me.AutoPostBack = False
MyBase.AddAttributesToRender(writer)
If bAutoPostBack Then
MyBase.Attributes.Remove("onchange")
sScript = String.Format("__doPostBack('{0}',{1})", Me.ClientID, "this.selectedIndex")
writer.AddAttribute(HtmlTextWriterAttribute.Onchange, sScript)
Me.AutoPostBack = True
End If
End Sub
在頁面上放置一個 TBDropDownList 控制項,設定與上述案例相同的成員清單。
<bee:TBDropDownList ID="DropDownList2" runat="server" AutoPostBack="True">
<asp:ListItem Value="0">張三</asp:ListItem>
<asp:ListItem Value="1">李四</asp:ListItem>
<asp:ListItem Value="2">王五</asp:ListItem>
<asp:ListItem Value="2">陳六</asp:ListItem>
</bee:TBDropDownList>
執行程式查看 TBDropDownList 控制項的 HTML 原始碼,呼叫 __doPostBack 函式的參數已經被修改,eventArgument 參數會傳入該控制項的 selectedIndex。
<select name="DropDownList2" id="DropDownList2" onchange="__doPostBack('DropDownList2',this.selectedIndex)">
<option selected="selected" value="0">張三</option>
<option value="1">李四</option>
<option value="2">王五</option>
<option value="2">陳六</option>
</select>
[超過字數限制,下一篇接續本文]
▼ ADVERTISEMENT ▼
廠商來幫忙
邦友收藏動態
- 三論專案的價格與成本 (ace33022)
- [Day 30]簡介軟體開發相關角色與UML產出模組-7 (ace33022)
- 如何在windos7的預覽窗格中預覽PDF (ace33022)
- 中國谷歌警告谷姐侵權 (chiehwen)
- 政府機房共構露曙光 (euros1002)
- 邁向eGov 2.0 優質網路政府 (euros1002)
- 顛覆傳統的新BI (euros1002)
- 政府廣發工商憑證,企業線上交易如何運用? (euros1002)
- 整合通訊也能DIY (euros1002)
- 如果購買W7 Ultimate 繁體中文版,想要確認若經由MUI轉換成日文介面,語音辨識功能是否就可以辨識日文? (mf0519)
- 5 本超優免費的自學 Linux 電子書 (scottchen)
- 常用網路管理工具 Getif (Get Interfaces)教學 (kaiin323)
- 6款Windows平臺免費備份工具 (tomtom123)
- 關於Cisco、linux、MySQL、Oracle、unix一些命令手冊 (fran633)
- 穩定的感覺會咬人 (heero1219248)
- 化繁為簡的工作拆解手法 (brgodman)
- 關於CCNA一些自我學習資料大全~! (51pass)
- 系統分析師必須思考的8個問題 (arnolin)
- 10 個不可或缺的 Linux/Unix 指令速查表 (scottchen)
- 用群組原則輕鬆管理使用者電腦 (raytracy)
安裝「收藏快捷鍵」,可以讓邦友直接透過Google工具列上的按扭,快速收藏站內、站外的網頁。
相關問答
- [ASP.NET 控制項實作 Day1] 建立 ASP.NET 伺服器控制項專案
- [ASP.NET 控制項實作 Day2] 建立第一個伺服器控制項
- [ASP.NET 控制項實作 Day11] ActiveX 伺服器控制項
- [ASP.NET 控制項實作 Day3] 擴展現有伺服器控制項功能
- 鐵人賽的疑問?
- 最後一天 -- 鐵人賽對我的意義!!!
- [ASP.NET 控制項實作 Day9] 控制項常用 Attribute 介紹(2)
- 收到鐵人賽的T-shirt啦~~ (有圖有真相)
- [ASP.NET 控制項實作 Day4] 複合控制項
- [ASP.NET 控制項實作 Day10] Media Player 控制項
- [ASP.NET 控制項實作 Day30] 整合 jQuery ContextMenu 的右鍵選單控制項
- [ASP.NET 控制項實作 Day19] 控制項設計階段的外觀
- 鐵人賽之期末報告
- [ASP.NET 控制項實作 Day7] 設定工具箱的控制項圖示
- 鐵人賽之期中報告
- 第二屆鐵人賽開始啦,想參賽的必讀哦
- 2009第2屆iT邦幫忙鐵人賽得獎名單公佈
- [ASP.NET 控制項實作 Day27] 控制項依 FormView CurrentMode 自行設定狀態
- [ASP.NET 控制項實作 Day8] 控制項常用 Attribute 介紹(1)
- [ASP.NET 控制項實作 Day5] 屬性與 ViewState







