2015-08-06 25 views
19

Sto utilizzando la nuova funzionalità Model Binding per WebForms, con .NET Framework versione 4.5.1. Quello che spero di ottenere è di escludere di alcuni dei binding a due vie, in base ad alcune condense.Modello Web Form Binding: come omettere il binding per il controllo non visibile?

Mi piace molto il (speriamo ora famoso) blog post series, by Scott Guthrie. A implementare una pagina di modifica utilizzando il numero di approccio a due da Web Forms Model Binding Part 3: Updating and Validation (ASP.NET 4.5 Series)

Ecco quello che ho: (semplificato, in ElementEdit.aspx):

<asp:FormView runat="server" ID="FormViewElement" RenderOuterTable="false" DefaultMode="Edit" DataKeyNames="ElementId" 
    ItemType="Business.Entities.Element" 
    SelectMethod="GetElement" 
    UpdateMethod="UpdateElement"> 
    <EditItemTemplate> 
     <asp:Panel runat="server" DefaultButton="ButtonSpeichern"> 
      <fieldset> 
       /*some databound controls*/ 
       <asp:Panel runat="server" Visible="<%# !Item.CurrentElementData.SomeCondition() %>"> 
        /*more databound controls*/ 
       </asp:Panel> 
       /*the submit button ("ButtonSpeichern")*/ 
      </fieldset> 
     </asp:Panel> 
    </EditItemTemplate> 
</asp:FormView> 

Come si vede, c'è una condizione per la visibilità sul pannello interno avvolto con "più controlli di dati". Questi dovrebbero legare solo quando i conditioni sono veri e sono visibili. Altrimenti non dovrebbero legare e non cambiare i valori.

L'aggiornamento funziona come nel post di Scott (semplificato, in xxPage.cs), che è una classe base generica di tipo Elemento:

protected virtual bool UpdateEntity(int id) { 
    T existing = UseCase.GetItem(id); //gets the original element  

    TryUpdateModel(existing); //SHOULD NOT update the invisible databound controls, but does 

    ValidateExistingEntity(existing);  
    if (ModelState.IsValid) { 
     UseCase.Update(existing); 
     return true; 
    } 
    ShowErrors(ModelState); 
    return false; 
} 

Qui, dopo la chiamata a TryUpdateModel(), i controlli invisibili hanno aggiornato il modello, che è quello che volevo evitare.

Come omettere dinamicamente l'associazione dati per alcuni elementi, in base a una condizione, anche se impostarli invisibili non aiuta?

UPDATE: Ora ho creare una soluzione alternativa, che risolve il problema per me oggi: ho semplicemente creato due pagine aspx con il loro rispettivo codice dietro. A seconda dei campi che l'utente deve modificare con successo, chiamo la pagina appropriata in primo luogo.

Questo, tuttavia, non risolve il problema di fondo, che è il databinding condizionale.

+0

chiunque sia interessato a partecipare a [webforms] (http://stackoverflow.com/documentation/webforms)? –

risposta

7

Questo è più un algoritmo che una soluzione codificata.

Mi piace utilizzare una classe separata per dire MyData.cs per gestire i miei aggiornamenti di dati e passare elementi dell'interfaccia utente tramite i metodi di questa classe. Sono come le stored procedure, ma puoi creare query all'interno del tuo progetto.

Se c'è variazione tra cui i controlli sono visibili e non, mi consiglia:

MyBindingMethod(array[] of the controls){ 
    // Loop through array updating data. 
    // Or loop through array and call a second method to update the data. 
} 

Dinamicamente è possibile controllare la visibilità dei controlli e quindi aggiungerli alla matrice o meno pass per la metodo vincolante.

Se i controlli che commutano visibilità sono costanti è possibile utilizzare due metodi separati, per aggiornare in modo selettivo:

MyBindingMethodAll(){ 
    // Update all controls. 

} 

MyBindingMethodVisible(){ 
    // Update controls that remain visible. 

} 

quindi chiamare i metodi delle MyData.cs dal aspx.cs. Il trucco consiste nel mantenere il controllo dell'associazione dei dati all'interno del tuo C# e puoi determinare esattamente cosa viene aggiornato, dove e quando.

Sono lieto di fornire un esempio di lavoro più dettagliato, se sei in grado di fornire più codice.


Modifica Update per contribuire a chiarire soluzione

Utilizzando una classe separata per gestire l'associazione di dati, l'elemento di visualizzazione può essere passato a un metodo di questa classe separata. Ho usato le stored procedure.

classe ManageData

public static void SelectAllSomething(DropDownList list) 
    { 
     // Clear any previously bound items. 
     list.Items.Clear(); 
     // SqlConnection. 
     SqlConnection con = new SqlConnection(conString); 
     // Create new command and parameterise. 
     SqlCommand cmd = new SqlCommand(); 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.CommandText = "MyStoredProcedure"; 

     cmd.Connection = con; 
     try 
     { 
      // Open connection and bind data to GUI. 
      con.Open(); 

      list.DataSource = cmd.ExecuteReader(); 
      list.DataTextField = "Name"; 
      list.DataValueField = "ID"; 
      list.DataBind(); 

     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
     finally 
     { 
      con.Close(); 
      con.Dispose(); 
     } 
    } 

Da te aspx.cs chiamare il metodo dalla classe ManageData.

ManageData.SelectAllCat(MyDropDownList); 

Utilizzo dello stesso principal.
Senza vedere il tuo layout, posso solo darti un esempio di concetto.

  • se si dispone di TextBox che si desidera controllare.

TextBox1, TextBox2, TextBox3, .../

public static void AddText(List<TextBox> MyTextBoxes) 
{ 
    for(int i=0; i<MyTextBoxes.Count();i++){ 
     MyTextBoxes.[i].Text = // What means you are using. 
    } 

} 

Dalle aspx.cs

public List<TextBox> FindVisibleTextBoxes(){ 

    List<TextBox> MyTextBoxes = new List<TextBox>(); 
    if(TextBox1.Visible== true){ 
     MyTextBoxes.Add(TextBox1); 
    } 

    return MyTextBoxes; 

} 

Passo lista di testo in modo da ManageData.

Questo può meglio modularizzato, in base alle proprie esigenze e si può passare più di una lista or a List of Objects per passare attraverso un mix eterogeneo di controlli.

Questo è solo un concetto, ci sono molti modi per fare le cose. Spero che lo trovi utile per sviluppare più modi per risolvere il tuo dilemma.

+2

Grazie. Questo sembra essere davvero dinamico. Tuttavia sembra abbastanza coinvolto e toglie la semplicità e la bellezza della nuova rilegatura del modello. Spero di trovare una soluzione più semplice. Ma, ho implementato una soluzione alternativa ora, vedere l'aggiornamento. – Marcel

+1

@Marcel la tua soluzione suona bene. Dovrei lasciare questa risposta qui? pensi che potrebbe aiutare gli altri? Se avrò tempo, aggiornerò per soddisfare la tua ultima domanda, l'ho appena visto. –

+1

Si prega di lasciarlo. Alla fine lo accetterò. È possibile fornire un collegamento sul metodo di associazione che riceve una serie di controlli da gestire in modo specifico? Ho fatto una rapida ricerca su google, ma non ho trovato nulla di più lontano finora. – Marcel

Problemi correlati