Si non sono sparito... solo un pò assente. Btw, in questi giorni mi sono dovuto/voluto scontrare di persona con il problema della compatibilità dei broswer e i css... tra IE7 e IE8 le cose cambiano molto e se non si vuole ricorrere al metà tag “X-UA-Compatible = IE=EmulateIE7” un’alternativa potrebbe essere quella di usare i “Microsoft Conditional Comments” e lasciare che la pagina risolva client-side il corretto css da usare. Tutto questo è in contrasto con l’uso dei Themes dove tutti i css presenti nella cartella vengono inseriti nella pagina senza distinzione... ovviamente le buone e pratiche osservazioni, “Themes prevent the use of Microsoft's CSS Conditional Comments”, vengono chiuse e catalogate come come “Won't Fix”.
In rete ho trovato diverse idee... anche sovracomplesse; una soluzione decisamente interessante è questa "How to take control of style sheets in ASP.NET Themes with the StylePlaceholder and Style control". Perchè interessante? Perchè mi ha dato l’idea su come muovermi su qualcosa di più semplice e pratico. In fondo è un problema semplice e mi piacerebbe risolverlo con un metodo semplice. Ecco come mi sono mosso.
Ho stabilito che il nome del mio css deve contenere anche la regola che indica se deve essere incluso o scartato per la richiesta corrente in accordo con le caratteristiche del browser. Ho voluto definire solo due regole semplici:
Si potrebbero aggiungere regole più complicate ma attualmente queste coprono tutti i casi d’uso a me necessari. Ho quindi definito uno user control che incluso nella pagina va ad escludere i css aggiunti ma che non sono concordi con il browser che sta facendo richiesta. Ecco il codice che ne è uscito.
[ToolboxData("<{0}:ConditionalCssThemeControl runat=\"server\"></{0}:ConditionalCssThemeControl>")]
public class ConditionalCssThemeControl: WebControl
{
const char CONDITIONAL_CHAR = '@';
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.Page.LoadComplete += new EventHandler(Page_LoadComplete);
}
void Page_LoadComplete(object sender, EventArgs e)
{
string browserType = this.Page.Request.Browser.Type;
var removeCandidate = Page.Header.Controls.OfType<HtmlLink>()
.Where(link => !IsValidCss(link.Href, browserType)).ToList();
removeCandidate.ForEach(Page.Header.Controls.Remove);
}
protected override void Render(HtmlTextWriter writer)
{
//il controllo agisce solo server side
}
private bool IsValidCss(string href, string browserType)
{
if (href.Contains(CONDITIONAL_CHAR))
{
string[] segments = href.Split(new char[] { CONDITIONAL_CHAR }, 2);
string condition = segments[1];
bool matchBrowser = condition.EndsWith(string.Concat(browserType, ".css"),
StringComparison.InvariantCultureIgnoreCase);
if (condition[0] == '!')
{
//il css è da escludere per lo specifico browser
return !matchBrowser;
}
else
{
//il css è indicato per lo specifico browser
return matchBrowser;
}
}
else
{
//il css non ha condizioni di utilizzo
return true;
}
}
}
Quindi nell’head della Page o della MasterPage aggiungo un’istanza del controllo.
<mb:ConditionalCssThemeControl runat="server" id="condCssTheme" />
La mia cartella del Theme risulta come segue.
Quello che mi piace di questa soluzione è che posso indicare le condizioni semplicemente e non ho dovuto mettere riferimenti al path del Themes nel codice... come molti esempi viene fatto.
oO0( ... altre possibilità? )
posted @ giovedì 2 luglio 2009 15:52