错误:SelectedValue 无效,因为它不存在于项目列表中
-
19-09-2019 - |
题
我有一个绑定到 ObjectDataSource (objStudentDetails) 的 Gridview。在 Gridview 的编辑/插入模式下,其中一个字段是 DropDownList,它从查找表中获取其选择列表选项。我将此 DropDownList 绑定到另一个代表查找表的 ObjectDataSource 控件 (objStateList)。只要 objStudentDetails ObjectDataSource 中的值与 objStateList ObjectDataSource 中的值之一匹配(至少在非空字符串值的情况下),它就可以正常工作。
objStateList 具有以下值(来自加载它的存储过程 - ID#6 是一个空字符串 ''):
StateId State
----------- -----
6
4 AL
1 GA
3 KY
2 TN
objStudentDetails 具有以下值(来自加载它的存储过程):
FirstName LastName State
----------- ---------- -----
tone smith TN
或者它可能具有以下结果集(State 是一个空字符串 - ''):
FirstName LastName State
----------- ---------- -----
jenny johnson
在第一个 objStudentDetails 结果集中,EditItemTemplate 中的状态 DropDownList 显示良好。然而,在第二个结果集中,我收到此错误:
'ddlEditState' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value
我认为,由于我的查找表有一个带有空字符串的值,因此状态为空字符串的 objStudentDetails 值会匹配,但有些东西没有按照我期望的方式工作。
这是 Gridview 中的 EditItemTemplate 代码:
<EditItemTemplate>
<asp:Panel ID="panEditState" runat="server">
<asp:DropDownList ID="ddlEditState" runat="server" CssClass="GridviewDropdownlist"
DataSourceID="objStateList" DataTextField="State" DataValueField="State"
SelectedValue='<%# Bind("State") %>'
Width="50px">
</asp:DropDownList>
</asp:Panel>
</EditItemTemplate>
以及 objStateList,它调用一个方法,传递要查询的查找表的参数:
<asp:ObjectDataSource ID="objStateList" runat="server" SelectMethod="GetDropdownData" TypeName="AIMLibrary.BLL.DropdownData">
<SelectParameters>
<asp:Parameter Name="itemsToGet" DefaultValue="state" />
</SelectParameters>
</asp:ObjectDataSource>
有任何想法吗?
解决方案
由两个DropDownLists' AppendDataBoundItems属性设置为true启动。接着,通过将以下<asp:ListItem>
元件每个的DropDownList添加NULL列表项,以便声明标记如下:
<asp:DropDownList ID="Categories" runat="server"
DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'
AppendDataBoundItems="True">
<asp:ListItem Value="">[nothing selected]</asp:ListItem>
</asp:DropDownList>
其他提示
我怀疑有许多不同的方案,可能会导致该错误。就我而言,我不得不向下放置在模板字段的下降。下拉结合于它自己的ObjectDataSource,其SelectedValue属性从GridView的自己的(单独的)的数据源绑定到字段。
现在,用我特定的情况下,这个问题是一个竞争状态。 GridView的数据源正在填充并绑定前的下拉菜单中有轮到他们。这也意味着项目已经通过自己绑定创建的下拉列表前的下拉菜单selectedvalues正在设置。
我敢肯定,我们有了一个更好的解决办法,但我没有研究太多的时间。我断开GridView和从他们的数据源的下拉菜单(意思是,除去从设计师的分配)和编程选择绑定。这样一来,我可以明确地结合在下拉菜单中,这样它们的项值将可在GridView控件本身绑定。
到目前为止,一切都很好。的代码在Page_Load只是几个额外的行
AppendDataBoundItems =“真”>作品,但不是在所有情况。制作下拉列表里面的GridView仍然是微软必须解决一个谜。他们说,发展是ASP比PHP快得多。嗯,这是对这个的小的问题,我的第三天,仍然没有解决。
好的,因为这是一个常见问题,我想实际发布一个答案是值得的:经过一番查找后,我发现了两种解决方案 - 一种是补丁,另一种是真正的解决方案。
修补:设置 DDL 设置
AppendDataBoundItem=true
并且手动将一个元素添加到列表中(即“请选择”,值为空):< asp:DropDownList ID="DropDownList5 runat="服务器" AppendDataBoundItems="True" ...> <asp:listItem>请选择< /asp:listItem> < /asp:dropdownlist>
这似乎在大约 80% 的情况下有效。当我必须升级 DDL 使用的现有(和工作)查询以允许另一个参数值时,我遇到了一个奇怪的情况 - 查询类似于 SELECT ID, Name from EMPLOYEES where Department =@Department
和原来 @Department
只能等于“计划员”和“车间” - 添加“物流”后,DDL 神秘地停止工作,仅针对部门的新值。
- 正确的解决方案:期间绑定DDL
GridView_RowDataBound
事件(感谢 本文
我的参数被视为标签中的文本(在其他地方设置)
protected void GridView5_RowDataBound(object sender, GridViewRowEventArgs e)
{
//********** this is a workaround for the annoying problem with dropdownlist in gidview without adding new item ************
if (e.Row.RowType == DataControlRowType.DataRow && GridView5.EditIndex == e.Row.RowIndex)
{
DropDownList DropDownList5 = (DropDownList)e.Row.FindControl("DropDownList5");
string query = "SELECT gkey as empID, name FROM [employees] where department=@department";
SqlCommand command = new SqlCommand(query);
command.Parameters.AddWithValue("@department", lblDepartment.Text);
DropDownList5.DataSource = GetData(command);
DropDownList5.DataTextField = "name";
DropDownList5.DataValueField = "empID";
DropDownList5.DataBind();
}
以及 GetData 方法:
private DataTable GetData (SqlCommand cmd)
{
string strConnString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt= new DataTable())
{
sda.Fill(dt);
return dt;
}
}
}
}