【发布时间】:2011-08-18 16:12:01
【问题描述】:
首先有关于这个的问题(DropDownList has a SelectedValue which is invalid because it does not exist in the list of items、DropDownList "has a SelectedValue which is invalid because it does not exist in the list of items"、asp:DropDownList Error: 'DropDownList1' has a SelectedValue which is invalid because it does not exist in the list of items)并且有建议的解决方法,但我的问题是为什么会发生这种情况。更重要的是,我对建议的解决方法不满意,我觉得它们很丑。
所以有一个带有下拉列表和按钮的页面:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="TestWebApplication.WebForm2" ViewStateMode="Disabled" %>
<html lang="en" >
<body>
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="ddlTest" runat="server">
</asp:DropDownList>
<asp:Button Text="Test" ID="btnTest" runat="server" onclick="btnTest_Click" />
</div>
</form>
</body>
</html>
我将 ddlTest 与 Page_Init 上的一些项目绑定,然后在 btnTest_Click 中再次绑定:
using System;
namespace TestWebApplication
{
public partial class WebForm2 : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
//SelectedIndex is -1, SelectedValue is "", SelectedItem is null
ddlTest.DataSource = new[] { 1, 2, 3 };
ddlTest.DataBind();
ddlTest.SelectedValue = "3";
}
protected void btnTest_Click(object sender, EventArgs e)
{
//SelectedIndex is 2, SelectedValue is "3", SelectedItem is {3}
ddlTest.ClearSelection();
//SelectedIndex is 0, SelectedValue is "1", SelectedItem is {1}
ddlTest.SelectedIndex = -1; //Nothing changes including SelectedIndex
ddlTest.SelectedValue = ""; //Nothing changes including SelectedValue
ddlTest.Items.Clear();
//SelectedIndex is -1, SelectedValue is "", SelectedItem is null
ddlTest.DataSource = null; //Nothing changes except for the DataSource property
ddlTest.DataSource = new[] { 1, 2 };
ddlTest.DataBind();//Exception!
//'ddlTest' has a SelectedValue which is invalid because it does not exist in the list of items.
//Parameter name: value
}
}
}
为什么会出现异常。我尝试了这些的不同版本,但它们都不起作用。我尝试仅使用 ClearSelection,但仍然遇到相同的异常。这是控件中的错误还是我想念的东西。其他问题的丑陋解决方法是唯一的解决方案吗?
注意 - 即使按钮被移除并且所有代码都在单个事件处理程序中移动,该错误也是可重现的。只需绑定一次设置选定的值并再次绑定。
【问题讨论】:
-
我不确定您所看到的确切内容,但我不明白您为什么采用这种方法。首先,我将创建一个单独的方法来初始化控件。然后我会从
Page_Load调用这个方法,如果!IsPostBack。然后我会再次从您的按钮单击处理程序中调用相同的方法在 进行任何更改之后。你有什么理由使用Page_Init事件吗? -
@J. Wood +1 推荐 Page_Load,而不是 Page_Init。页面生命周期可能非常令人沮丧,如果可能的话,最好避免在其深处徘徊。
-
可能是他试图避免弄脏 ddl 的视图状态......他显然没有在这里尝试完成任何事情,这只是一个演示错误情况的练习。
-
我使用 Page_Init 以避免覆盖 DropDownList 中的回发信息(我已禁用 ViewState,如 page 指令中所述)。现实世界的示例是一个按钮 Delete,它从列表中删除选定的值并重新绑定它。在这种情况下,我当然可以删除它或将值设置为其他值,但可能存在更复杂的情况,即删除更难(如果我必须删除几个相关项目怎么办)。 @Jonathan Wood 在现实世界的代码中,我确实有一个在两个地方都可以调用的方法。