Domanda

Ho un Gridview che si lega a un ObjectDataSource (objStudentDetails).Nella modalità di modifica/inserimento di Gridview uno dei campi è un DropDownList che ottiene le opzioni dell'elenco di selezione da una tabella di ricerca.Ho questo collegamento DropDownList a un altro controllo ObjectDataSource (objStateList) che rappresenta la tabella di ricerca.Funziona bene purché il valore in objStudentDetails ObjectDataSource corrisponda a uno dei valori in objStateList ObjectDataSource, almeno nel caso di un valore di stringa non vuoto comunque.

objStateList ha questi valori (dal proc memorizzato che lo carica - ID#6 è una stringa vuota ''):

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

L'objStudentDetails ha questi valori (dal proc memorizzato che lo carica):

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

Oppure potrebbe avere questo set di risultati (Lo stato è una stringa vuota - ''):

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

Nel primo set di risultati objStudentDetails lo stato DropDownList in EditItemTemplate viene visualizzato correttamente.Nel secondo set di risultati, tuttavia, ottengo questo errore:

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

Penserei che, poiché la mia tabella di ricerca ha un valore con una stringa vuota, il valore objStudentDetails con una stringa vuota per lo stato corrisponderebbe, ma qualcosa non funziona come mi aspetto.

Ecco il mio codice EditItemTemplate da 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 objStateList, che chiama un metodo che passa un parametro di quale tabella di ricerca interrogare:

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

Qualche idea?

È stato utile?

Soluzione

Inizia impostando la proprietà AppendDataBoundItems entrambi DropDownList true. Successivamente, aggiungere il NULL ListItem aggiungendo il seguente elemento <asp:ListItem> ad ogni DropDownList in modo che il markup dichiarativo appare come:

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

Altri suggerimenti

Sospetto che ci siano molti scenari diversi che possono causare questo errore.Nel mio caso, avevo un menu a discesa inserito in un campo modello.Il menu a discesa era associato al proprio objectdatasource e la sua proprietà selectvalue era associata a un campo dell'origine dati (separata) di gridview.

Ora, con il mio scenario specifico, il problema era una condizione di gara.L'origine dati di gridview veniva popolata e associata PRIMA che i menu a discesa avessero il loro turno.Ciò significava anche che i valori selezionati dei menu a discesa venivano impostati PRIMA che gli elementi dei menu a discesa fossero creati tramite le proprie associazioni.

Sono sicuro che ci deve essere una soluzione migliore, ma non ho avuto molto tempo per la ricerca.Ho disconnesso la visualizzazione della griglia e i menu a discesa dalle rispettive origini dati (ovvero, rimuovendo le assegnazioni dal progettista) e ho optato per il collegamento a livello di codice.In questo modo, posso associare esplicitamente i menu a discesa in modo che i valori dei relativi elementi siano disponibili quando viene associata la visualizzazione della griglia stessa.

Fin qui tutto bene.Solo poche righe di codice extra nel file Page_Load

AppendDataBoundItems = "True"> opere, ma non in tutti i casi. Fare DropDownList all'interno GridView è ancora un mistero che Microsoft deve risolvere. Si dice che lo sviluppo è ASP è molto più veloce di PHP. Ebbene questo è il mio terzo giorno in questa piccolo problema e hanno ancora una soluzione.

OK, dal momento che questo è un problema comune Credo che il suo valore di inviare in realtà una risposta:. Dopo un sacco di guardarsi intorno ho trovato due soluzioni - bene, un cerotto e una vera

  1. Patching: Impostare l'impostazione AppendDataBoundItem=true DDL anda aggiungere manualmente un elemento alla lista (vale a dire "Selezionare" con il valore null):

       Seleziona                             

Questo sembra funzionare in circa l'80% dei casi. Ho avuto una strana situazione in cui ho dovuto aggiornare esistente (e di lavoro) di query utilizzato da DDL per consentire a un altro valore del parametro - Query era qualcosa di simile a SELECT ID, Name from EMPLOYEES where Department =@Department e in origine @Department poteva che essere uguale a "pianificatori" e "laboratorio" - dopo l'aggiunta "Logistica" DDL misteriosamente smesso di funzionare solo per il nuovo valore del dipartimento.

  1. soluzione esatta: Associare il DDL durante l'evento GridView_RowDataBound (bagnatura grazie a Questo articolo

Il mio parametro viene preso come un testo dall'etichetta (istituito da qualche altra parte)

    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 il metodo 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;
            }
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top