Non è possibile caricare DropDownList su FormView dal codice dietro?
-
19-09-2019 - |
Domanda
Ho un UserControl, contenente un FormView, che contiene una DropDownList. Il FormView è associato a un controllo dati.
In questo modo:
<asp:FormView ID="frmEdit" DataKeyNames="MetricCode" runat="server" DefaultMode="Edit" DataSourceID="llbDataSource" Cellpadding="0" >
<EditItemTemplate>
<asp:DropDownList ID="ParentMetricCode" runat="server" SelectedValue='<%# Bind("ParentMetricCode") %>' />
</EditItemTemplate>
<asp:FormView>
Sto cercando di popolare il DropDownList dal codebehind. Se questo non era contenuta in un FormView, io normalmente solo farlo nell'evento Page_Load. Tuttavia, questo non funziona all'interno di un FormView, come non appena provo a farlo, l'accesso alla DropDownList nel codice, cioè:.
theListcontrol = CType(formView.FindControl(listControlName), ListControl)
... i dati meccanismo del FormView legame viene richiamato, che, naturalmente, cerca di impegnare la DropDownList all'origine dati sottostante, causando un 'ParentMetricCode' ** ha un SelectedValue che è valido perché non esiste in l'elenco degli elementi. "Nome del parametro: il valore ...". Errore, dal momento che la DropDownList non è ancora stato popolato
Ho provato eseguendo il carico nel caso DataBinding () del FormView, ma poi:
theListcontrol = CType(formView.FindControl(listControlName), System.Web.UI.WebControls.ListControl)
... non riesce, come il FormView.Controls.Count = 0 in quel punto.
E 'questo impossibile? (Io non voglio dover utilizzare un ObjectDataSource secondaria di impegnare la DropDownList a)
Soluzione 3
Ok, trovato "una" soluzione:
1. Chiamare la funzione DDL Popola dall'evento FormView_ItemCreated
.
2. Modificare il codice per popolare il DDL in questo modo:
Public Overloads Shared Sub BindListControl(Of theLLBLgenEntityType As EntityBase) _
(ByVal formView As FormView, _
ByVal listControlName As String, _
ByVal theCollection As CollectionCore(Of theLLBLgenEntityType), _
ByVal DataValueField As EntityField, _
ByVal DataTextField As EntityField, _
ByVal IncludeEmptyItem As Boolean)
If formView.CurrentMode = FormViewMode.Edit Then
Dim theListcontrol As System.Web.UI.WebControls.ListControl
theListcontrol = CType(formView.FindControl(listControlName), System.Web.UI.WebControls.ListControl)
For Each entity As theLLBLgenEntityType In theCollection
theListcontrol.Items.Add(New ListItem(entity.Fields(DataTextField.Name).CurrentValue.ToString, entity.Fields(DataValueField.Name).CurrentValue.ToString))
Next
If IncludeEmptyItem Then
theListcontrol.Items.Insert(0, New ListItem("", ""))
End If
End Sub
E 'un po sembra a bollire in fondo verso il basso per, non si può fare "Databinding" aggiuntiva, programmaticamente in fase di esecuzione, all'interno di un FormView.
(Qualcuno sa il motivo per cui la formattazione del mio codice è avvitato in su in questo post ??)
Aggiornamento
Questa soluzione solleva ancora un altro lotto di problemi, relativi ad inserire nuovi elementi. Dopo un sacco di avvitamento intorno alla fine ho trovato un modo per aggirare questo. A questo punto, io sono praticamente al punto in cui mi sento di raccomandare sia di evitare il controllo FormView del tutto, o sicuramente evitare di alterare programatically controlli associati. Si spera, magari utilizzando i controlli di dati separati per ogni DropDownList potrebbe funzionare meglio, ma questo potrebbe essere un pio desiderio pure.
Altri suggerimenti
Attuare la OnDataBinding
direttamente sul tuo DropDownList
.
Quando si associa il tuo formview ad alcuni dati del OnDataBinding
per la DropDownList
spareranno. A questo punto è possibile caricare i valori desiderati nella lista e associare il valore selezionato all'elenco caricato pure.
Ecco un esempio:
<asp:DropDownList ID="ParentMetricCode" runat="server" OnDataBinding="ParentMetricCode_DataBinding" />
Quindi implementare l'OnDataBinding:
protected void ParentMetricCode_DataBinding(object sender, System.EventArgs e)
{
DropDownList ddl = (DropDownList)(sender);
// Fill the list items however you want
ddl.Items.Add(new ListItem("1", "1"));
ddl.Items.Add(new ListItem("2", "2"));
// etc...
// Set the selected value
ddl.SelectedValue = Eval("ParentMetricCode").ToString();
}
Quando DataBind
tuo FormView, tutto inizierà a fare la sua magia:)
Anche se il caricamento dei dati della lista per il vostro DropDownList
da un DB o qualcosa che si potrebbe desiderare di memorizzare nella cache è dal momento che ogni 'riga' dei dati farà sì che il caricamento dei dati della lista.
Modifica Dal momento che si pensa che non è possibile che ho scritto una demo applicazione rapida per dimostrare come funziona:
Nel file aspx includere questo:
<asp:FormView ID="fvTest" runat="server">
<ItemTemplate>
<asp:DropDownList ID="ddlTest" runat="server" OnDataBinding="ddlTest_DataBinding"></asp:DropDownList>
</ItemTemplate>
</asp:FormView>
Poi, nel tuo .cs file:
public class MockData
{
public string ID { get; set; }
public string Text { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
List<MockData> lst = new List<MockData>();
lst.Add(new MockData() { ID = "3", Text = "Test3" });
fvTest.DataSource = lst;
fvTest.DataBind();
}
protected void ddlTest_DataBinding(object sender, System.EventArgs e)
{
DropDownList ddl = (DropDownList)(sender);
ddl.Items.Add("1");
ddl.Items.Add("2");
ddl.Items.Add("3");
ddl.Items.Add("4");
ddl.Items.Add("5");
ddl.SelectedValue = Eval("ID").ToString();
}
Eseguire il codice ... il DropDownList
sarà caricato con tutti i valori e impostato sul valore selezionato corretto che è stato impostato nell'oggetto deriso.
Non so cos'altro posso fare per dimostrarlo meglio ... Credo che la vostra mancante come associazione dati funziona realmente. Se si tenta di farlo a livello FormView
, i controlli non vengono effettuati fino a quando il FormView
è in realtà legato. Quando accade l'associazione, è possibile attivare ogni controllo all'interno del modello di fare qualcosa per la sua attuazione è evento OnDataBinding
. A quel punto l'iterazione corrente di oggetto associato ei suoi valori sono disponibili e che è dove si vede il mio codice fare un Eval("ID")
.
Si sta lavorando per me con l'evento OnDataBound invece di OnDataBinding che si verifica prima che venga creato il controllo.
<asp:DropDownList ID="ddlCountry" runat="server" DataSourceID="SqlDataSrcCountries" AutoPostBack="True" DataTextField="name" DataValueField="code" OnDataBound="ddlCountry_DataBound">
</asp:DropDownList>
Codice-behind:
Protected Sub ddlCountry_DataBound(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ddlCountry As New DropDownList
Dim strCountry As String = String.Empty
Dim lstItemToFind As New ListItem
ddlCountry = FormViewUsers.FindControl("ddlCountry")
strCountry = Eval("country")
lstItemToFind = ddlCountry.Items.FindByValue(strCountry)
If (Not IsNothing(lstItemToFind)) Then
ddlCountry.SelectedValue = strCountry
End If
End Sub
Se si utilizza questo su altri modelli rispetto alla Edit è sufficiente per convalidare:
If (FormViewUsers.CurrentMode = FormViewMode.Edit) Then
End If