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

发布于 2024-08-02 20:10:15 字数 1953 浏览 5 评论 0原文

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

有什么想法吗?

I have a Gridview which binds to an ObjectDataSource (objStudentDetails). In edit/insert mode of the Gridview one of the fields is a DropDownList that gets it's pick list options from a lookup table. I have this DropDownList binding to another ObjectDataSource control (objStateList) which represents the lookup table. It works fine as long as the value in the objStudentDetails ObjectDataSource matches one of the values in the objStateList ObjectDataSource, at least in the case of a non empty string value anyway.

The objStateList has these values (from the stored proc that loads it - ID#6 is an empty string ''):

StateId     State
----------- -----
6             
4           AL
1           GA
3           KY
2           TN

The objStudentDetails has these values (from the stored proc that loads it):

FirstName   LastName   State
----------- ---------- -----
tone        smith      TN

Or it could have this result set (State is an empty string - ''):

FirstName   LastName   State
----------- ---------- -----
jenny       johnson     

In the first objStudentDetails resultset the state DropDownList in the EditItemTemplate shows up fine. In the second resultset, however, I get this error:

'ddlEditState' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value 

I would think that since my lookup table has a value with an empty string, that the objStudentDetails value with an empty string for state would match, but something isn't working the way I am expecting it to.

Here is my EditItemTemplate code from the Gridview:

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

And the objStateList, which calls a method passing a parameter of which lookup table to query:

<asp:ObjectDataSource ID="objStateList" runat="server" SelectMethod="GetDropdownData"     TypeName="AIMLibrary.BLL.DropdownData">
<SelectParameters>
<asp:Parameter Name="itemsToGet" DefaultValue="state" />
</SelectParameters>
</asp:ObjectDataSource>

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

隔纱相望 2024-08-09 20:10:15

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

Start by setting both DropDownLists' AppendDataBoundItems property to true. Next, add the NULL ListItem by adding the following <asp:ListItem> element to each DropDownList so that the declarative markup looks like:

<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>
满地尘埃落定 2024-08-09 20:10:15

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

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

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

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

I suspect there are many different scenarios that can cause this error. In my case, I had a drop down placed in a template field. The drop down was bound to its own objectdatasource, and its selectedvalue property was bound to a field from the gridview's own (separate) datasource.

Now, with my specific scenario, the problem was a race condition. The gridview's datasource was being populated and bound BEFORE the dropdowns had their turn. This also meant that the dropdowns' selectedvalues were being set BEFORE the dropdowns' items had been created through their own bindings.

I'm sure there's got to be a better solution, but I didn't have much time for research. I disconnected the gridview and the dropdowns from their datasources (meaning, removing the assignments from the designer) and opted bind programmatically. That way, I can explicitly bind the dropdowns so that their items' values will be available when the gridview itself is bound.

So far, so good. Just a few extra lines of code in the Page_Load

花心好男孩 2024-08-09 20:10:15

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

AppendDataBoundItems="True"> works but not in all cases. Making dropdownlist inside GridView is still a mystery which Microsoft has to resolve. They say development is ASP is much quicker than PHP. Well this is my third day on this small problem and still have no solution.

妳是的陽光 2024-08-09 20:10:15

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

  1. 修补:
    设置 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 只能等于“Planners”和“Workshop” - 添加“Logistics”后,DDL 神秘地仅针对部门的新值停止工作。

  1. 正确的解决方案:在 GridView_RowDataBound 事件期间绑定 DDL(感谢 这篇文章

我的参数是从标签中获取的文本(在其他地方设置)

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

OK, since this is a common problem I guess its worth to actually post an answer: After a lot of looking around I've found two solutions - well, one patch and one real one.

  1. Patching:
    Set the DDL setting AppendDataBoundItem=true anda add manually one element to the list (i.e. "Please Select" with null value):

    < asp:DropDownList ID="DropDownList5 runat="server" AppendDataBoundItems="True" ... >
    < asp:ListItem>Please Select< /asp:ListItem>
    < /asp:DropDownList>

This seems to work in about 80% of cases. I had a weird situation when I had to upgrade existing (and working) query used by DDL to allow another value of parameter - Query was something similar to SELECT ID, Name from EMPLOYEES where Department =@Department and originally @Department could only be equal to "Planners" and "Workshop" - after adding "Logistics" DDL mysteriously stopped working ONLY for the new value of department.

  1. Proper solution: Bind the DDL during the GridView_RowDataBound event (fount thanks to This article

My parameter is taken as a text from the label (set up somewhere else)

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

And the GetData method:

   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;
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文