Generalmente quando dobbiamo recuperare dati da un ListView, se non ci troviamo all'interno dell'evento ItemDataBound siamo portati a credere che l'unica strada percorribile sia quella di recuperare i relativi controlli mediante il metodo FindControl e successivamente leggerne le proprietà. In realtà esiste una soluzione migliore ed è costituita dal metodo ExtractItemValues, tramite il quale è possibile estrarre tutti i dati contenuti all'interno di una riga.
Consideriamo come esempio il seguente template che visualizza alcune informazioni (nome, disponibilità in magazzino, ordini pendenti) di una serie di prodotti contenuti in una DataTable:
<asp:ListView runat="server" ID="MyListView" DataKeyNames="ID" OnItemCommand="MyListView_ItemCommand"> <LayoutTemplate> <asp:PlaceHolder runat="server" ID="itemPlaceholder" /> </LayoutTemplate> <ItemTemplate> Nome: <asp:Label runat="server" ID="label_1" Text='<%# Bind("Name") %>' /> Disponibilità: <asp:Label runat="server" ID="label_2" Text='<%# Bind("Stock") %>' /> Ordini: <asp:Label runat="server" ID="label1" Text='<%# Bind("Orders") %>' /> <asp:Button runat="server" ID="OrderButton" Text="Controlla" /> </ItemTemplate> </asp:ListView>
Al click del button dobbiamo calcolare la differenza tra scorte di magazzino e ordini pendenti per valutare se possiamo effettivamente accettare l'ordine. Allo scopo, registriamo un event handler per l'evento RowCommand:
protected void MyListView_ItemCommand(object sender, ListViewCommandEventArgs e) { if (e.Item.ItemType == ListViewItemType.DataItem) { OrderedDictionary _dictionary = new OrderedDictionary(); MyListView.ExtractItemValues(_dictionary, e.Item, true); int _orders = Convert.ToInt32((_dictionary["Orders"])); int _stock = Convert.ToInt32(_dictionary["Stock"]); int _restock = _orders - _stock; if (_restock > 0) { e.Item.Controls.Add(new Literal { Text = "Ordinare: " + _restock.ToString() }); } else { e.Item.Controls.Add(new Literal { Text = "Magazzino sufficiente" }); } } }
Dopo aver verificato che l'item che contiene il button sia di tipo ListViewDataItem (per non incorrere in un'eccezione a runtime), proseguiamo creando una nuova istanza dell'oggetto OrderDictionary, che va passato al metodo ExtractItemValues insieme all'item dal quale estrarre i valori. A questo punto possiamo recuperare i dati necessari direttamente dal dictionary usando come chiavi le stesse utilizzate nelle espressioni di bind, ossia i nomi delle relative proprietà o colonne. Il resto del codice esegue poche e semplici operazioni, recuperando i valori associati alle chiavi per poi convertirli in interi, effettuare un semplice calcolo e decidere il messaggio da mostrare.
Utilizzando quest'approccio è possibile eliminare del tutto la necessità di ricorrere a FindControl, legando quindi la nostra logica al vero e proprio dato e non al particolare template utilizzato nel markup.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Effettuare il deploy di immagini solo da container registry approvati in Kubernetes
Personalizzare l'errore del rate limiting middleware in ASP.NET Core
Eseguire un metodo asincrono dopo il set di una proprietà in Blazor 8
Effettuare il binding di date in Blazor
Short-circuiting della Pipeline in ASP.NET Core
Load test di ASP.NET Core con k6
Utilizzare la libreria Benchmark.NET per misurare le performance
Implementare il throttling in ASP.NET Core
I più letti di oggi
- Miglioramenti nelle performance di Angular 16
- Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
- HTML5 con CSS e JavaScript
- Ottimizzazione dei block template in Angular 17
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!