Le operazioni di cancellazione o di modifica dei record o recupero dati visualizzati da un controllo GridView sono molto semplici quando utilizziamo controlli ad associazione dati quali SQLDataSource o ObjectDataSource, spesso tuttavia accade di dover associare al GridView collezioni di oggetti e le normali funzionalità del GridView vengono a mancare improvvisamente. L’argomento è molto vasto, e spesso tra le ricerche che portano a questo miserevole blog trovo riferimenti a queste tematiche.
Tenterò dunque, compatibilmente con le modeste capacità di sintesi in mio possesso, di illustrare una tecnica empirica che ho utilizzato di recente per trarmi d’impaccio in una situazione in cui ho effettuato il bind di un GridView a una collection di oggetti…
Avevo la necessità di recuperare l’id di un oggetto da cancellare su un webservice dal quale recuperavo i dati, il GridView in oggetto è il seguente:
<asp:GridView ID=”grd” runat=”server” AutoGenerateColumns=”False” DataKeyNames=”IdSchedulazione”
OnRowCommand=”grd_RowCommand” ShowFooter=”True” OnRowDeleting=”grd_RowDeleting”>
<Columns>
<asp:CommandField ButtonType=”Image” DeleteImageUrl=”~/assett/16-em-cross.png” SelectImageUrl=”~/assett/action_forward.gif”
ShowDeleteButton=”True” ShowSelectButton=”True” />
<asp:TemplateField>
<HeaderTemplate>
<asp:LinkButton runat=”server” ID=”lkbNome” CommandName=”Sort” CommandArgument=”Nome”
Text=”Nome” ForeColor=”White”></asp:LinkButton>
</HeaderTemplate>
<ItemTemplate>
<asp:Label runat=”server” ID=”lblNome” Text=’<%# Eval(”Nome”) %>’></asp:Label>
<asp:HiddenField ID=”HiddenField1″ runat=”server” Value=’<%# Eval(”IdSchedulazione”) %>’ />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<asp:LinkButton runat=”server” ID=”lkbNext” CommandName=”Sort” CommandArgument=”ProssimaSchedulazione”
Text=” Prossima schedulazione ” ForeColor=”White”></asp:LinkButton>
</HeaderTemplate>
<ItemTemplate>
<asp:Label runat=”server” ID=”lblNext” Text=’<%# Eval(”ProssimaSchedulazione”) %>’></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
<asp:Label runat=”server” ID=”lkbCountDown” Text=”CountDown “></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label runat=”server” ID=”lblNext2″ Text=’<%# Eval(”ToLeft”) %>’></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Le parti evidenziate in rosso mostrano i dettagli che ci occuperemo:
<asp:CommandField ButtonType=”Image” DeleteImageUrl=”~/assett/16-em-cross.png” SelectImageUrl=”~/assett/action_forward.gif”
ShowDeleteButton=”True” ShowSelectButton=”True” />
Il CommandField sopracitato determina la generazione di una colonna contenente due pulsanti, il pulsante delete, e il pulsante select, entrambi avranno già impostati CommandName e CommandArgument ai valori corretti, ho utilizzato un CommandField al posto di un TemplateField(più versatile) per il semplice motivo che utilizzando un TemplateField non mi riesce di far intercettare l’evento desiderato, ma questa è un’altra storia…
<asp:Label runat=”server” ID=”lblNome” Text=’<%# Eval(”Nome”) %>’></asp:Label>
<asp:HiddenField ID=”HiddenField1″ runat=”server” Value=’<%# Eval(”IdOggetto”) %>’ />
In una colonna ho inserito i due controlli, uno mostrerà la proprietà “Nome” dell’oggetto, l’altro manterrà il valore che mi risulterà utile per l’operazione di delete. Nella sintassi <%# Eval(”Nome”) %> il simbolo # indica un associazione a una origine dati nel momento che richiameremo il metodo Bind( ) del controllo, la funzione Eval viene utilizzata per definire l’associazione in sola lettura della proprietà dell’oggetto.
Da codice ho definito il seguente codice per effettuare il bind del GridView:
private void Binda(string sortExpression)
{
_service= new Service();
Oggetti[] list = _service.GetOggetti( );
…
IEnumerable<Oggetti> t =(IEnumerable<Oggetti>) (from sc in list orderby sc.GetPropertyValue(sortExpression) select sc);
grd.DataSource= t.ToArray();
grd.DataBind();
}
Come dicevo, in questo caso ho utilizzato un webservice come origine dati, e tramite un webmethod ho inizializzato un vettore di oggetti, l’ho specificato come DataSource del controllo e ho richiamato il metodo Databind( ). Per visualizzare i dati questo è sufficiente, ma per cancellare un record?
OnRowDeleting=”grd_RowDeleting”
La proprietà sopracitata indica un metodo che intercetta il comando delete del GridView:
protected void grd_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
GridView v=(GridView)sender;
HiddenField hd = (HiddenField)v.Rows[e.RowIndex].Cells[1].Controls[3];
_service= new Service();
bool result=_service.DeleteOggetto(int.Parse(hd.Value));
}
Nel metodo ho operato in maniera brutale, lo so, ma in effetti il procedimento funziona. Sapendo che il controllo HiddenField nella seconda colonna del GridView c’é indubitabilmente, ho utilizzato l’indice fornito dal parametro e del metodo per determinare la riga corrente, dopodichè è bastato impostare un breakpoint e utilizzare le funzionalità del debugger di VisualStudio per scoprire quale controllo contenesse l’HiddenField, ne ho impostato un riferimento, e ho utilizzato il valore per richiamare il metodo del webservice per cancellare il record.
Empirico come dicevo, ma efficace…
bye.

0 Risposte a “[ GridView ] Recuperare dati da una riga di un GridView”