Pergunta

Eu tenho um gridview que se liga a um ObjectDataSource (objStudentDetails). Em editar / modo de inserção de um Gridview dos campos é um DropDownList que fica com o da lista de seleção opções a partir de uma tabela de pesquisa. I ter de ligação esta DROPDOWNLIST para outro controlo ObjectDataSource (objStateList) que representa a tabela de consulta. Ele funciona bem, desde que o valor no objStudentDetails ObjectDataSource corresponde a um dos valores na objStateList ObjectDataSource, pelo menos no caso de um valor string não vazia de qualquer maneira.

O objStateList tem esses valores (do proc armazenado que carrega-lo - ID # 6 é uma string vazia ''):

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

Os objStudentDetails tem esses valores (do proc armazenado que carrega):

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

Ou poderia ter este conjunto de resultados (Estado é uma string vazia - ''):

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

Nos primeiros objStudentDetails ResultSet o DropDownList estado nos shows EditItemTemplate até bem. No segundo conjunto de resultados, no entanto, eu recebo este erro:

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

Gostaria de pensar que desde a minha tabela de referência tem um valor com uma cadeia vazia, que o valor objStudentDetails com uma string vazia para o estado iria corresponder, mas algo não está funcionando da maneira que eu estou esperando que ele.

Aqui está o meu código EditItemTemplate do 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>

E o objStateList, que chama um método passando um parâmetro do que consulta à tabela de consulta:

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

Todas as idéias?

Foi útil?

Solução

Comece definindo AppendDataBoundItems ambas as DropDownLists propriedade para true. Em seguida, adicione o NULL ListItem adicionando o seguinte elemento <asp:ListItem> a cada DropDownList para que os olhares marcação declarativa como:

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

Outras dicas

Eu suspeito que há muitos cenários diferentes que podem causar este erro. No meu caso, eu tinha um drop down colocado em um campo de modelo. O drop-down foi obrigado a seu próprio objectdatasource, e sua propriedade SelectedValue foi vinculado a um campo da própria fonte de dados do gridview (separado).

Agora, com o meu cenário específico, o problema era uma condição de corrida. fonte de dados do gridview estava sendo povoada e presos aos dropdowns teve sua vez. Isto também significa que os menus suspensos selectedvalues ??estavam sendo definido antes de os menus suspensos itens havia sido criado através de suas próprias ligações.

Eu tenho certeza que tem de haver uma solução melhor, mas eu não tinha muito tempo para a investigação. I desligado o gridview e os menus suspensos a partir de suas fontes de dados (ou seja, remover as atribuições do desenhador) e ligam-se optou por meio de programação. Dessa forma, eu posso explicitamente ligam os menus suspensos para que os valores de seus itens estarão disponíveis quando o gridview em si é obrigado.

Até agora, tão bom. Apenas algumas linhas de código extra no Page_Load

AppendDataBoundItems = "true"> obras, mas não em todos os casos. Fazendo dropdownlist dentro GridView ainda é um mistério que a Microsoft tem de resolver. Eles dizem que o desenvolvimento é ASP é muito mais rápido do que o PHP. Bem, este é o meu terceiro dia nesta pequena problema e ainda não têm solução.

OK, uma vez que este é um problema comum eu acho que vale a pena para realmente postar uma resposta:. Depois de um monte de olhar ao redor eu encontrei duas soluções - bem, um remendo e um verdadeiro

  1. Patching: Defina a configuração DDL anda AppendDataBoundItem=true adicionar manualmente um elemento à lista (por exemplo, "Por favor, selecione" com o valor null):

    Selecione

Isso parece funcionar em cerca de 80% dos casos. Eu tive uma situação estranha quando eu tive que atualizar existente (e trabalho) consulta usada por DDL para permitir que outro valor do parâmetro - Consulta era algo semelhante a SELECT ID, Name from EMPLOYEES where Department =@Department e originalmente @Department só poderia ser igual a "planejadores" e "Workshop" - depois de adicionar "Logística" DDL misteriosamente parou de funcionar SOMENTE para o novo valor do departamento.

  1. solução adequada: Bind do DDL durante o evento GridView_RowDataBound (molhagem graças a Este artigo

Meu parâmetro é tomado como um texto da etiqueta (criado em outro 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();
    }

E o 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top