Los Temas son una estupenda característica que se añadió en ASP.NET 2.o y que permite separar el aspecto de nuestra aplicación de la disposición de los elementos de las páginas ASPX. De este modo puedes cambiar todo el aspecto estético de la aplicación completa o de una parte de ella con sólo cambiar un ajuste en web.config correspondiente. Los temas son junto con las (mal traducidas) páginas principales (Master Pages) un gran paso adelante para independizar el diseño de la interfaz del desarrollo del código.

El caso es que aprovechando estas características mucha gente ha implementado portales en los que se le deja elegir al usuario qué tema quiere aplicar a la aplicación, de modo que cada uno elige la combinación de colores, etc... que más le guste. Combinándolo con la API de perfiles (Profile) se consigue almacenar la preferencia y así mejorar la experiencia del usuario. El cambio dinámico de tema, al igual que el de Master Pages, se suele hacer en el evento Pre_Init de las páginas, pues en momentos posteriores del ciclo de vida de ésta ya no es posible.

Para dar a escoger entre los distintos temas existentes a los usuarios, mucha gente opta por almacenar una lista con sus nombres en algún lado (web.config, un archivo XML, la base de datos...), cuando en realidad no es necesario en absoluto, puesto ya tenemos una lista siempre disponible. Y es que cada tema se corresponde con una subcarpeta dentro de la carpeta especial de la aplicación llamada App_Themes. Sabido esto es muy fácil obtener una lista de los temas disponibles sacando un listado de las subcarpetas de App_Themes, así:

string[] carpetas = ListaCarpetas(HttpContext.Current.Server.MapPath(@"~/App_Themes"));

El método ListaCarpetas se limita a comprobar si la ruta existe y en caso afirmativo devuelve la lista completa de subcarpetas:

private static string[] ListaCarpetas(string rutaFisica)
{
  if (!Directory.Exists(rutaFisica)) return null;

  return Directory.GetDirectories(rutaFisica);
}

Vamos que no tiene nada. Únicamente notar que GetDirectories devuelve las rutas completas de las carpetas y nosotros necesitamos sus nombres por lo que antes de utilizarlos debemos extraerlos. Luego lo vemos entero.

Obtener los temas pero esta vez TODOS los temas.

"¿Todos? ¿Qué me estás contando?" pensará alguno a estas alturas. Bueno, el verdadero "truco" viene a continuación... Resulta que aunque no es algo muy conocido, en ASP.NET es posible definir temas globales, que estarán disponibles para todas las aplicaciones aunque éstas no tengan una carpeta App_Themes.

Si colocamos carpetas que contienen temas en la ruta "%Windir%\Microsoft.NET\Framework\[Version]\ASP.NETClientFiles\Themes", siendo [Version] la versión de ASP.NET actual, éstos estarán disponibles para su uso en cualqueir aplicación.

Por lo tanto para tener un verdadero listado completo de temas debemos obtener también una lista de esas carpetas. Aparte de tener que saber esto, el código no tiene demasiado truco. Si acaso poder averiguar la versión actual de ASP.NET y averiguar la ruta de la carpeta de Windows (puedes verlo en el código fuente), más abajo.

He escrito una clase sencilla llamada AppThemes que tiene un método estático llamado Disponibles, que devuelve un ArrayList con los nombres de todos los temas disponibles, tanto locales como globales. Con ella, para obtener una lista de temas disponibles y poder ofrecérselos en una lista a los usuarios, basta con escribir AppThemes.Disponibles(); y listo, así que puede resultar útil.

Puedes descargarte esta clase con un ejemplo desde aquí (ZIP, 4 kB).

Escrito por un humano, no por una IA