Come ho detto, per cose semplici basta richiamare un metodo che si occupa del "rendering", ad esempio sulla lista utenti ho una colonna con "smile" per utente "on-line", oppure "lucchetto chiuso" per utente bloccato, rimane vuota altrimenti. Ogni stato esclude l'altro.
<ItemTemplate><%# CreateImageOnLineOrLockout(((WebUser)Container.DataItem)) %></ItemTemplate>
protected string CreateImageOnLineOrLockout(WebUser webUser)
{
if (webUser.IsOnline)
{
return "<img src=\"Images/Icons/smile.gif\" alt=\"online\">";
}
else if(webUser.IsLockedOut)
{
return "<img src=\"Images/Icons/lock.gif\" style=\"vertical-align:middle\" alt=\"" + (string)GetLocalResourceObject("Blocked") + "\">";
}
return "";
}
In una situazione più complicata, griglia di prodotti di sito e-commerce/ricambi, ricorro al DataBound di ogni riga in cui verifico la tipologia di utente, se appartiene ad un certo ruolo, se ha crediti sufficienti, se il prodotto è disponibile, se appartiene alle sue competenze ecc... ecc...
In base a tali valori per ogni riga ed a valori precedentemente memorizzati (ha un listino assegnato, ha il fido bloccato... ) posso mostrare diverse "soluzioni".
E' chiaro che per tali operazioni il DataBound è d'obbligo.
In certe vecchie pagine (mi vergogno a dirlo) ho addirittura brutalmente impostato Visible = False per le colonne X e Y, con X e Y hard-coded nella pagina!
protected void gridParts_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (base.RoleProperty.HasBasket) /// create the textbox and icons for add spare part to basket
{
SparePart sparePart = (SparePart)e.Row.DataItem;
if (webUser.RoleCode != Role.ROLE_CODE_BRANCH_SERVICE_CENTER)
{
if (sparePart.Disponibility <= 0)
{
//Resources.General.Pieces_abbr
e.Row.Cells[COLUMN_INDEX_DISPONIBILITY].Controls.Add(new LiteralControl(ELEMENT_IMAGE_AVAILABILITY_OFF));
}
else
{
e.Row.Cells[COLUMN_INDEX_DISPONIBILITY].Controls.Add(new LiteralControl(ELEMENT_IMAGE_AVAILABILITY_ON));
}
}
if (sparePart.Price > 0)
{
string textboxId = "q_" + e.Row.RowIndex;
string textbox = "<input type=\"text\" id=\"" + textboxId + "\" class=\"textbox w35\" />";
/// Todo: set spare part code in a hidden textbox
string js_basket_order = "addPart('" + Order.ORDER_TYPE_ORDER_CODE + "','" + HttpUtility.HtmlEncode(sparePart.Code) + "', '" + textboxId + "');";
string js_basket_estimate = "addPart('" + Order.ORDER_TYPE_ESTIMATE_CODE + "','" + HttpUtility.HtmlEncode(sparePart.Code) + "', '" + textboxId + "');";
string image_basket_order = "<img src=" + IMAGE_BASKET_ORDER + " onclick=\"" + js_basket_order + "\" class=\"hand\" />";
string image_basket_estimate = "<img src=" + IMAGE_BASKET_ESTIMATE + " onclick=\"" + js_basket_estimate + "\" class=\"hand\" />";
((HtmlGenericControl)e.Row.FindControl("b")).InnerHtml = textbox + " " + image_basket_order + " " + image_basket_estimate;
}
}
}
}
Nell'esempio (terribile) qui sopra vengono aggiunti controlli in vario modo, sia tramite la sintassi e.Row.Cells[COLUMN_INDEX],
sia con il più classico (e corretto) e.Row.FindControl(controlID).
Si rende però necessario usare controlli lato server (se possibile è meglio evitarli per rimanere più "leggeri") per poterli ricercare nell'evento, mentre con il modo di procedere esposto sopra si può evitare questa ricerca, posizionando la chiamata della funzione di render/format proprio nel punto in cui si vuole "scrivere" qualcosa.
<%# MetodoCheTornaUnaStringa() %> equivale a <%= MetodoCheTornaUnaStringa() %> che è quanto di più vicino ci sia a <% Response.Write() %>.
Ciò che fa realmente la differenza tra l'usare dei WebControl o meno è il fatto che questi persistono il loro stato (e valori) tra un post e l'altro, se invece si procede con un metodo "manuale" si perde tale vantaggio e si deve pensare al modo migliore per persistere i dati tra un post e l'altro (io solitamente sfrutto il Viestate).
Ma qui si chiedeva consiglio per una semplice griglia di immagini, stiamo andando fuori tema...
ciao