顯示具有 DropDownList 標籤的文章。 顯示所有文章
顯示具有 DropDownList 標籤的文章。 顯示所有文章

2025年4月1日 星期二

[研究]DropDownList從資料庫抓出的值,不在下拉選項中的處理

[研究]DropDownList從資料庫抓出的值,不在下拉選項中的處理

2025-04-01

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19


DropDownListClass.cs

using System;
using System.Web.UI.WebControls;

namespace WebApplicationProject1.Controls
{
    public class DropDownListClass : DropDownList
    {
        protected override void PerformDataBinding(System.Collections.IEnumerable dataSource)
        {
            // 過濾掉 DropDownList 在 DataBinding 時可能會發生的 Exception 問題!
            // 如果 Exception 發生,預設會選取第一個下拉選項!
            try
            {
                base.PerformDataBinding(dataSource);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                ArgumentOutOfRangeException o = ex;
            }
        }
    }
}

(完)

相關

2022年3月19日 星期六

[研究]DropDownList下拉選單的恩怨情仇(五)連動選單項目不存在的預選

 [研究]DropDownList下拉選單的恩怨情仇(五)連動選單項目不存在的預選

2022-3-19

環境:Visual Studio 2022 + ASP.NET + Web Application + WebForm + C#

續這篇

[研究]DropDownList下拉選單的恩怨情仇(一)'DropDownList1' 擁有的 SelectedValue 無效,因為它不在項目清單中。
https://shaurong.blogspot.com/2022/03/dropdownlistdropdownlist1-selectedvalue.html

[研究]DropDownList下拉選單的恩怨情仇(二)使用料庫儲存選項清單http://shaurong.blogspot.com/2022/03/dropdownlist.html

[研究]DropDownList下拉選單的恩怨情仇(三)已儲存項目不再提供於資料庫選項名單
http://shaurong.blogspot.com/2022/03/dropdownlist_19.html

[研究]DropDownList下拉選單的恩怨情仇(四)項目不存在的預選https://shaurong.blogspot.com/2022/03/dropdownlist_15.html

(下圖)新版分類選項

(下圖)舊版購買結果歷史紀錄 (芭樂、蘿蔔已經不再目前上面選項中)

Default2.aspx 


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

<!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>
    <asp:SqlDataSource ID="SqlDataSource_FruitVegeType" runat="server"
        ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>"
        SelectCommand="SELECT N'' AS FruitVegeType UNION SELECT DISTINCT FruitVegeType FROM [FruitVegeList]"></asp:SqlDataSource>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>"
        SelectCommand="SELECT * FROM [FruitVegeRecord] WHERE ([sn] = @sn)"
        UpdateCommand="UPDATE [FruitVegeRecord] SET [FVType] = @FVType, [FruitBuy] = @FruitBuy WHERE [sn] = @sn">
        <SelectParameters>
            <asp:QueryStringParameter Name="sn" QueryStringField="sn" Type="Int32" DefaultValue="1" />
        </SelectParameters>
        <UpdateParameters>
            <asp:Parameter Name="FVType" Type="String" />
            <asp:Parameter Name="FruitBuy" Type="String" />
            <asp:Parameter Name="sn" Type="Int32" />
        </UpdateParameters>
    </asp:SqlDataSource>

    <form id="form1" runat="server">
        <div>
            <asp:DetailsView ID="DetailsView1" runat="server" Height="50px"
                DefaultMode="Edit" Caption="編輯"
                AutoGenerateRows="False" DataKeyNames="sn"
                DataSourceID="SqlDataSource1">
                <Fields>
                    <asp:BoundField DataField="sn" HeaderText="sn" InsertVisible="False" ReadOnly="True" SortExpression="sn" />
                    <asp:TemplateField HeaderText="FVType" SortExpression="FVType">
                        <EditItemTemplate>
                            <asp:TextBox ID="TextBox_FVType" runat="server" Text='<%# Bind("FVType") %>' Visible="false"></asp:TextBox>
                            <asp:DropDownList ID="DropDownList_FruitVegeType" runat="server"
                                AutoPostBack="true" DataTextField="FruitVegeType"
                                DataValueField="FruitVegeType"
                                DataSourceID="SqlDataSource_FruitVegeType"
                                OnSelectedIndexChanged="DropDownList_FruitVegeType_SelectedIndexChanged">
                            </asp:DropDownList>
                            <asp:SqlDataSource ID="SqlDataSource_FruitVegeName" runat="server"
                                ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>"
                                SelectCommand="SELECT N'' AS FruitVegeName UNION (SELECT FruitVegeName FROM [FruitVegeList] WHERE ([FruitVegeType] = @FruitVegeType))">
                                <SelectParameters>
                                    <asp:ControlParameter ControlID="DropDownList_FruitVegeType" Name="FruitVegeType" ConvertEmptyStringToNull="false" PropertyName="SelectedValue" />
                                </SelectParameters>
                            </asp:SqlDataSource>
                        </EditItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="FruitBuy" SortExpression="FruitBuy">
                        <EditItemTemplate>
                            <asp:TextBox ID="TextBox_FruitBuy" runat="server" Text='<%# Bind("FruitBuy") %>' Visible="false"></asp:TextBox>
                            <asp:DropDownList ID="DropDownList_FruitVegeName" runat="server"
                                DataSourceID = "SqlDataSource_FruitVegeName"
                                AutoPostBack="true" DataTextField="FruitVegeName"
                                DataValueField="FruitVegeName"
                                OnSelectedIndexChanged="DropDownList_FruitVegeName_SelectedIndexChanged">
                                <asp:ListItem></asp:ListItem>
                            </asp:DropDownList>
                        </EditItemTemplate>
                    </asp:TemplateField>
                    <asp:CommandField ShowEditButton="True" />
                </Fields>
            </asp:DetailsView>
        </div>
    </form>
</body>
</html>

Default2.aspx.cs 中部分


using System;
using System.Web.UI.WebControls;

namespace WebApplication3
{
    public partial class Default2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        protected void DropDownList_FruitVegeType_SelectedIndexChanged(object sender, EventArgs e)
        {
            TextBox TextBox_FVType = (TextBox)DetailsView1.FindControl("TextBox_FVType");
            DropDownList DropDownList_FruitVegeType = (DropDownList)DetailsView1.FindControl("DropDownList_FruitVegeType");
            TextBox_FVType.Text = DropDownList_FruitVegeType.SelectedValue;
        }
        protected void DropDownList_FruitVegeName_SelectedIndexChanged(object sender, EventArgs e)
        {
            TextBox TextBox_FruitBuy = (TextBox)DetailsView1.FindControl("TextBox_FruitBuy");
            DropDownList DropDownList_FruitVegeName = (DropDownList)DetailsView1.FindControl("DropDownList_FruitVegeName");
            TextBox_FruitBuy.Text = DropDownList_FruitVegeName.SelectedValue;
        }
    }
}

按下「編輯」按鈕後出現


(完)

[研究]DropDownList下拉選單的恩怨情仇(四)項目不存在的預選

 [研究]DropDownList下拉選單的恩怨情仇(四)項目不存在的預選

2022-3-19

環境:Visual Studio 2022 + ASP.NET + Web Application + WebForm + C#

續這篇

[研究]DropDownList下拉選單的恩怨情仇(一)'DropDownList1' 擁有的 SelectedValue 無效,因為它不在項目清單中。
https://shaurong.blogspot.com/2022/03/dropdownlistdropdownlist1-selectedvalue.html

[研究]DropDownList下拉選單的恩怨情仇(二)使用料庫儲存選項清單http://shaurong.blogspot.com/2022/03/dropdownlist.html

[研究]DropDownList下拉選單的恩怨情仇(三)已儲存項目不再提供於資料庫選項名單
http://shaurong.blogspot.com/2022/03/dropdownlist_19.html

之前下拉選單一定只出現第一項,改進一下;

若已存資料庫中項目不再存在,希望「編輯」畫面下拉選單預選空白;

若已存資料庫中項目存在,希望「編輯」畫面下拉選單預選該項目。

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" 
                OnRowDataBound="GridView1_RowDataBound" 
                >
                <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="TextBox_FruitBuy" runat="server" ReadOnly="true"
                                Text='<%# Bind("FruitBuy") %>'></asp:TextBox>
                            <asp:SqlDataSource ID="SqlDataSource_FruitName" runat="server"
                                ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>"
                                SelectCommand="SELECT * FROM [FruitList]"></asp:SqlDataSource>
                            <asp:DropDownList ID="DropDownList_FruitBuy" runat="server"
                                AutoPostBack="true"
                                DataSourceID="SqlDataSource_FruitName"
                                 AppendDataBoundItems="true"
                                DataTextField="FruitName" DataValueField="FruitName" 
                                OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
                                <asp:ListItem></asp:ListItem>
                            </asp:DropDownList>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="Label1" runat="server" Text='<%# Bind("FruitBuy") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
    </form>

</body>
</html>

Default.aspx.cs 中部分


using System;
using System.Web.UI.WebControls;

namespace WebApplication3
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            var row = GridView1.Rows[GridView1.EditIndex];
            TextBox TextBox_FruitBuy = (TextBox)row.FindControl("TextBox_FruitBuy");
            DropDownList DropDownList_FruitBuy = (DropDownList)row.FindControl("DropDownList_FruitBuy");
            TextBox_FruitBuy.Text = DropDownList_FruitBuy.SelectedValue;
        }

        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow 
                && e.Row.RowState == (DataControlRowState.Edit | DataControlRowState.Alternate))
            {
                if (e.Row.RowIndex == GridView1.EditIndex)
                {
                    TextBox TextBox_FruitBuy = (TextBox)e.Row.FindControl("TextBox_FruitBuy");
                    DropDownList DropDownList_FruitBuy = (DropDownList)e.Row.FindControl("DropDownList_FruitBuy");
                    if (DropDownList_FruitBuy.Items.Contains(new ListItem(TextBox_FruitBuy.Text)))
                    {
                        DropDownList_FruitBuy.SelectedValue = TextBox_FruitBuy.Text;
                    }
                    else
                    {
                        DropDownList_FruitBuy.SelectedValue = "";
                    }
                }
            }
        }
    }
}

按下「編輯」按鈕後出現

(下圖)芭樂不在下拉選單中,下拉選單預選空白


(下圖)香蕉在下拉選單中,下拉選單預選香蕉
這種情況下,可以設定 TextBox_FruitBuy 為Visible = "false" 隱藏掉 (因為有的需求方不想看到兩個控制項 (ASP.NET Control),或不想在該處看到 TextBox )

別忘了GridView1_RowUpdating()要檢查按下「更新」按鈕後,新值是否屬於新名單中選項。
甚至按下「取消」觸發的GridView1_RowCancelingEdit()也進行檢查。但也或許可以不用,看該欄位是否允許不選擇,也就是輸入空字串。

敝人遇過某種下拉選單,允許不選,選項有數千項,隨時增、減、改名,非敝人管理,也不會通知敝人,就合適這種情況。

(完)

[研究]DropDownList下拉選單的恩怨情仇(三)已儲存項目不再提供於資料庫選項名單

[研究]DropDownList下拉選單的恩怨情仇(三)已儲存項目不再提供於資料庫選項名單

2022-3-19

環境:Visual Studio 2022 + ASP.NET + Web Application + WebForm + C#

續這篇

[研究]DropDownList下拉選單的恩怨情仇(一)'DropDownList1' 擁有的 SelectedValue 無效,因為它不在項目清單中。
https://shaurong.blogspot.com/2022/03/dropdownlistdropdownlist1-selectedvalue.html

[研究]DropDownList下拉選單的恩怨情仇(二)使用料庫儲存選項清單http://shaurong.blogspot.com/2022/03/dropdownlist.html

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="TextBox_FruitBuy" runat="server" ReadOnly="true"
                                Text='<%# Bind("FruitBuy") %>'></asp:TextBox>
                            <asp:SqlDataSource ID="SqlDataSource_FruitName" runat="server"
                                ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>"
                                SelectCommand="SELECT * FROM [FruitList]"></asp:SqlDataSource>
                            <asp:DropDownList ID="DropDownList_FruitBuy" runat="server"
                                AutoPostBack="true"
                                DataSourceID="SqlDataSource_FruitName"
                                DataTextField="FruitName" DataValueField="FruitName" 
                                OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
                            </asp:DropDownList>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="Label1" runat="server" Text='<%# Bind("FruitBuy") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
    </form>

</body>
</html>

Default.aspx.cs 中部分


protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
    var row = GridView1.Rows[GridView1.EditIndex];
    TextBox TextBox_FruitBuy = (TextBox)row.FindControl("TextBox_FruitBuy");
    DropDownList DropDownList_FruitBuy = (DropDownList)row.FindControl("DropDownList_FruitBuy");
    TextBox_FruitBuy.Text = DropDownList_FruitBuy.SelectedValue;
}

按下「編輯」按鈕後出現

芭樂雖然不再於下拉選單提供,但不會再出現下面錯誤。
DropDownList1' 擁有的 SelectedValue 無效,因為它不在項目清單中。

別忘了GridView1_RowUpdating()要檢查按下「更新」按鈕後,新值是否屬於新名單中選項。
甚至按下「取消」觸發的GridView1_RowCancelingEdit()也進行檢查。

(完)

[研究]DropDownList下拉選單的恩怨情仇(二)使用料庫儲存選項清單

[研究]DropDownList下拉選單的恩怨情仇(二)使用料庫儲存選項清單

2022-3-19

環境:Visual Studio 2022 + ASP.NET + Web Application + WebForm + C#

續這篇,之前下拉選項寫死程式中,若項目多,或需要該下拉選單的地方多,可把清單放存放於資料庫中,免得增減項目要到處改程式。

[研究]DropDownList下拉選單的恩怨情仇(一)'DropDownList1' 擁有的 SelectedValue 無效,因為它不在項目清單中。
https://shaurong.blogspot.com/2022/03/dropdownlistdropdownlist1-selectedvalue.html

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:SqlDataSource ID="SqlDataSource2" runat="server"
                                ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>"
                                SelectCommand="SELECT * FROM [FruitList]"></asp:SqlDataSource>
                            <asp:DropDownList ID="DropDownList1" runat="server"
                                SelectedValue='<%# Bind("FruitBuy") %>'
                                DataSourceID="SqlDataSource2"
                                DataTextField="FruitName" DataValueField="FruitName">
                            </asp:DropDownList>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="Label1" runat="server" Text='<%# Bind("FruitBuy") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
    </form>
</body>
</html>


按下「編輯」按鈕後出現

(完)

[研究]DropDownList下拉選單的恩怨情仇(一)'DropDownList1' 擁有的 SelectedValue 無效,因為它不在項目清單中。

[研究]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:DropDownList ID="DropDownList1" runat="server" SelectedValue='<%# Bind("FruitBuy") %>'> <asp:ListItem>橘子</asp:ListItem> <asp:ListItem>香蕉</asp:ListItem> </asp:DropDownList> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label1" runat="server" Text='<%# Bind("FruitBuy") %>'></asp:Label> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </div> </form> </body> </html>

如果下拉選項的項目少,或選單只用一次 (其他地方只是讀出值),選項可以寫死在程式中,不用放資料庫中。

(下圖)執行結果如下,資料庫中目前儲存的值是「香蕉」,是選單的其中一項,所以「編輯」功能不會有問題。

如果某天香蕉不再是選項,把 

<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" 。

沒有絕對的最佳方法,也應該還有其他方式,依各種情境、需求方可接受方式,進行選擇。

(完)