Recuperare i dati da ListView di ASP.NET senza usare FindControl

di Marco Leoncini, in ASP.NET 3.5,

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:

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

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi