[研究]DropDownList下拉選單的恩怨情仇(一)'DropDownList1' 擁有的 SelectedValue 無效,因為它不在項目清單中。
2022-3-19
環境:Visual Studio 2022 + ASP.NET + Web Application + WebForm + C#
下拉選單是個好用的東西,可以省卻使用者自己輸入的麻煩,由其名稱很長的時候;也可以限制使用者只能選擇特定的輸入;但若日後選項因業務需求者產生變化,那就是麻煩的事情了。
(下圖)假設下拉選單有3個選項
(下圖)假設一筆購買紀錄 (省卻價格、購買者、日期、、、)Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication3.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>" DeleteCommand="DELETE FROM [FruitRecord] WHERE [sn] = @sn" InsertCommand="INSERT INTO [FruitRecord] ([FruitBuy]) VALUES (@FruitBuy)" SelectCommand="SELECT * FROM [FruitRecord]" UpdateCommand="UPDATE [FruitRecord] SET [FruitBuy] = @FruitBuy WHERE [sn] = @sn"> <DeleteParameters> <asp:Parameter Name="sn" Type="Int32" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="FruitBuy" DefaultValue="" ConvertEmptyStringToNull="false" Type="String" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="FruitBuy" DefaultValue="" ConvertEmptyStringToNull="false" Type="String" /> <asp:Parameter Name="sn" Type="Int32" /> </UpdateParameters> </asp:SqlDataSource> <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="sn" DataSourceID="SqlDataSource1"> <Columns> <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" /> <asp:BoundField DataField="sn" HeaderText="sn" InsertVisible="False" ReadOnly="True" SortExpression="sn" /> <asp:TemplateField HeaderText="FruitBuy" SortExpression="FruitBuy"> <EditItemTemplate> <%--<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("FruitBuy") %>'></asp:TextBox>--%> |
如果下拉選項的項目少,或選單只用一次 (其他地方只是讀出值),選項可以寫死在程式中,不用放資料庫中。
(下圖)執行結果如下,資料庫中目前儲存的值是「香蕉」,是選單的其中一項,所以「編輯」功能不會有問題。
如果某天香蕉不再是選項,把<asp:ListItem>香蕉</asp:ListItem> |
註解成
<%--<asp:ListItem>香蕉</asp:ListItem>--%> |
執行後,按下「編輯」按鈕就會出錯。(「資料完整性」有問題,儲存的資料應該是選項之一才對,DropDownList選不到符合儲存值的選項)
'DropDownList1' 擁有的 SelectedValue 無效,因為它不在項目清單中。
參數名稱: value
例外狀況詳細資訊: System.ArgumentOutOfRangeException: 'DropDownList1' 擁有的 SelectedValue 無效,因為它不在項目清單中。
********************************************************************************
解決:
方法一:如果「香蕉」選項,不是不再提供,而是改名為「台灣香蕉」,那把資料庫已儲存資料也改名為台灣香蕉可解決。
方法二:「編輯」畫面不要用下拉選單,改用TextBox,怕使用者亂輸入,就在 GridView1_RowUpdating() 中檢查輸入值是否屬於新的選項之一。但若選項名稱很長、或容易出錯,用 TextBox 不方便。
方法三:「香蕉」選項在「編輯」畫面下拉選單不移除,但在 GridView1_RowUpdating() 中檢查輸入值是否屬於新的選項之一。
方法四:方法三若很多選項不再提供,如何區別呢?改寫成如下,Value是實際值,Text顯示文字
<asp:ListItem Value="香蕉" Text="香蕉(廢除)">香蕉</asp:ListItem>
方法五:「編輯」畫面同時用 TextBox 和 DropDownList,TextBox有Bind(),放目前資料庫抓出的值,DropDownList 不放 Bind(),旁邊加上一按鈕,按下時把 DropDownList 選的值,放到 TextBox 去。不用按鈕則 DropDownList 加上屬性 AutoPostBack="True" 。
沒有絕對的最佳方法,也應該還有其他方式,依各種情境、需求方可接受方式,進行選擇。
(完)
沒有留言:
張貼留言