Pregunta

Tengo un Gridview que se vincula a un ObjectDataSource (objStudentDetails).En el modo de edición/inserción de Gridview, uno de los campos es DropDownList que obtiene sus opciones de lista de selección de una tabla de búsqueda.Tengo este enlace DropDownList a otro control ObjectDataSource (objStateList) que representa la tabla de búsqueda.Funciona bien siempre que el valor en objStudentDetails ObjectDataSource coincida con uno de los valores en objStateList ObjectDataSource, al menos en el caso de un valor de cadena que no esté vacío de todos modos.

ObjStateList tiene estos valores (del proceso almacenado que lo carga; el ID#6 es una cadena vacía ''):

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

ObjStudentDetails tiene estos valores (del proceso almacenado que lo carga):

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

O podría tener este conjunto de resultados (el estado es una cadena vacía - ''):

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

En el primer conjunto de resultados de objStudentDetails, el estado DropDownList en EditItemTemplate se muestra bien.Sin embargo, en el segundo conjunto de resultados aparece este error:

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

Pensaría que, dado que mi tabla de búsqueda tiene un valor con una cadena vacía, el valor de objStudentDetails con una cadena vacía para el estado coincidiría, pero algo no funciona como espero.

Aquí está mi código EditItemTemplate de 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>

Y objStateList, que llama a un método pasando un parámetro de qué tabla de búsqueda consultar:

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

¿Algunas ideas?

¿Fue útil?

Solución

Para empezar, establezca la propiedad AppendDataBoundItems ambos DropDownLists' true. A continuación, añadir el NULL ListItem añadiendo el siguiente elemento <asp:ListItem> a cada DropDownList para que el marcado declarativo se ve así:

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

Otros consejos

Sospecho que hay muchos escenarios diferentes que pueden causar este error.En mi caso, tenía un menú desplegable colocado en un campo de plantilla.El menú desplegable estaba vinculado a su propia fuente de datos de objeto, y su propiedad de valor seleccionado estaba vinculada a un campo de la propia fuente de datos (separada) de la vista de cuadrícula.

Ahora, con mi escenario específico, el problema era una condición de carrera.La fuente de datos de la vista de cuadrícula se estaba completando y vinculando ANTES de que llegaran los menús desplegables.Esto también significaba que los valores seleccionados de los menús desplegables se configuraban ANTES de que los elementos de los menús desplegables se hubieran creado a través de sus propios enlaces.

Estoy seguro de que tiene que haber una solución mejor, pero no tuve mucho tiempo para investigar.Desconecté la vista de cuadrícula y los menús desplegables de sus fuentes de datos (es decir, eliminé las asignaciones del diseñador) y opté por vincularme mediante programación.De esa manera, puedo vincular explícitamente los menús desplegables para que los valores de sus elementos estén disponibles cuando la vista de cuadrícula esté vinculada.

Hasta ahora, todo bien.Solo unas pocas líneas adicionales de código en Page_Load

AppendDataBoundItems = "true"> obras, pero no en todos los casos. Haciendo lista desplegable dentro de GridView es todavía un misterio que Microsoft tiene que resolver. Dicen que es el desarrollo ASP es mucho más rápido que PHP. Bueno este es mi tercer día en este pequeña problema y aún no tienen solución.

OK, ya que este es un problema común que supongo que vale la pena publicar en realidad una respuesta:. Después de mucho mirar a su alrededor que he encontrado dos soluciones - así, un parche y un real

  1. Parches: Establecer la configuración AppendDataBoundItem=true DDL Anda añadir manualmente un elemento de la lista (es decir, "Por favor seleccione" con un valor nulo):

       Seleccione                             

Esto parece funcionar en aproximadamente el 80% de los casos. Yo tenía una situación extraña cuando tuve que actualizar existente (y trabajar) consulta utilizada por los DDL para permitir que otro valor de parámetro - Consulta era algo similar a SELECT ID, Name from EMPLOYEES where Department =@Department y originalmente @Department sólo podía ser igual a "planificadores" y "taller" - después de añadir "Logística" DDL misteriosamente dejó de funcionar sólo para el nuevo valor del departamento.

  1. solución adecuada: Enlazar el DDL durante el evento GridView_RowDataBound (de mojado gracias a Este artículo

Mi parámetro se toma como un texto de la etiqueta (establecido en otro lugar)

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

Y el método 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;
            }
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top