【问题标题】:Error: SelectedValue which is invalid because it does not exist in the list of items错误:SelectedValue 无效,因为它不存在于项目列表中
【发布时间】:2010-11-21 23:34:04
【问题描述】:

我有一个绑定到 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

或者它可以有这个结果集(状态是一个空字符串 - ''):

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>

有什么想法吗?

【问题讨论】:

    标签: asp.net gridview drop-down-menu edititemtemplate


    【解决方案1】:

    首先将 DropDownLists 的 AppendDataBoundItems 属性设置为 true。接下来,通过将以下 &lt;asp:ListItem&gt; 元素添加到每个 DropDownList 来添加 NULL ListItem,以便声明性标记如下所示:

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

    【讨论】:

    • 效果很好 - 谢谢!我将它用于空列表项:
    • 我正在使用模型绑定,所以这个答案是最合适的。
    【解决方案2】:

    我怀疑有许多不同的情况会导致此错误。就我而言,我在模板字段中放置了一个下拉菜单。下拉列表绑定到它自己的 objectdatasource,它的 selectedvalue 属性绑定到 gridview 自己的(单独的)数据源中的一个字段。

    现在,在我的具体情况下,问题是竞争条件。在轮到下拉列表之前,gridview 的数据源已被填充和绑定。这也意味着下拉菜单的选定值是在下拉菜单项通过它们自己的绑定创建之前设置的。

    我确信一定有更好的解决方案,但我没有太多时间研究。我从他们的数据源中断开了 gridview 和下拉列表(意思是从设计器中删除分配)并选择以编程方式绑定。这样,我可以显式绑定下拉列表,以便在绑定 gridview 本身时可以使用它们的项目值。

    到目前为止,一切都很好。只需在 Page_Load 中增加几行代码

    【讨论】:

      【解决方案3】:

      AppendDataBoundItems="True"> 有效,但并非在所有情况下都有效。在 GridView 中制作下拉列表仍然是微软必须解决的一个谜。他们说开发是 ASP 比 PHP 快得多。好吧,这是我解决这个问题的第三天,但仍然没有解决方案。

      【讨论】:

        【解决方案4】:

        好的,因为这是一个常见问题,我想它值得实际发布一个答案:经过大量环顾后,我找到了两种解决方案 - 一个补丁和一个真正的。

        1. 修补: 设置 DDL 设置 AppendDataBoundItem=true 并手动将一个元素添加到列表中(即“请选择”为空值):

          请选择

        这似乎在大约 80% 的情况下有效。当我不得不升级 DDL 使用的现有(和工作)查询以允许另一个参数值时,我遇到了一个奇怪的情况 - 查询类似于 SELECT ID, Name from EMPLOYEES where Department =@Department 并且最初 @Department 只能等于“Planners”和“Workshop " - 添加“物流”后,DDL 神秘地停止了仅为部门的新价值工作。

        1. 正确的解决方案:在GridView_RowDataBound事件期间绑定DDL(感谢This article

        我的参数被当作标签中的文本(在其他地方设置)

            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;
                    }
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2012-02-10
          • 1970-01-01
          • 2010-11-25
          • 2013-04-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多