5

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

有任何想法吗?

4

4 回答 4

9

首先将 DropDownLists 的 AppendDataBoundItems 属性设置为 true。接下来,通过将以下<asp:ListItem>元素添加到每个 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>
于 2009-12-09T19:56:10.140 回答
1

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

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

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

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

于 2012-01-10T20:06:45.860 回答
0

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

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

    <asp:DropDownList ID="DropDownList5 runat="server" AppendDataBoundItems="True" ... > <asp:ListItem>请选择</asp:ListItem> </asp:DropDownList>

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

  1. 正确的解决方案:在活动期间绑定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;
            }
        }
    }
}
于 2014-11-13T19:13:21.253 回答
0

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

于 2011-07-05T18:47:58.517 回答