错误:SelectedValue无效,因为它在项目列表中不存在

时间:2009-08-22 23:03:08

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

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

有什么想法吗?

4 个答案:

答案 0 :(得分:9)

首先将DropDownLists的AppendDataBoundItems属性设置为true。接下来,通过向每个DropDownList添加以下<asp:ListItem>元素来添加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>

答案 1 :(得分:1)

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

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

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

到目前为止,这么好。只需在Page_Load

中添加几行代码

答案 2 :(得分:0)

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

答案 3 :(得分:0)

好的,因为这是一个常见问题,我认为实际发布答案是值得的:经过大量的回顾,我发现了两个解决方案 - 好吧,一个补丁和一个真正的补丁。

  1. 修补: 设置DDL设置AppendDataBoundItem=true并手动将一个元素添加到列表中(即&#34;请选择&#34;使用空值):

    &LT; asp:DropDownList ID =&#34; DropDownList5 runat =&#34; server&#34; AppendDataBoundItems =&#34;真&#34; ...&gt;   &LT; asp:ListItem&gt;请选择&lt; / ASP:的ListItem&GT;                             &LT; / ASP:DropDownList的&GT;

  2. 这似乎适用于大约80%的案例。当我不得不升级DDL使用的现有(和工作)查询以允许另一个参数值时,我遇到了一个奇怪的情况 - 查询与SELECT ID, Name from EMPLOYEES where Department =@Department类似,原来@Department只能等于&# 34;规划者&#34;和&#34;工作坊&#34; - 添加&#34;后勤&#34; DDL神秘地停止了工作,只为部门的新价值。

    1. 正确解决方案:在GridView_RowDataBound事件期间绑定DDL(感谢This article
    2. 我的参数被视为标签中的文本(在其他地方设置)

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