VB.NET PROGRAMMING PATTERN FOR THE PREFERENCES USABILITY MECHANISM Drafted by Francy Diomar Rodríguez, Software and Systems PhD Student, Facultad de Informática. Universidad Politécnica de Madrid. (fd.rodriguez@alumnos.upm.es) Content 1 Introduction... 1 2 Preferences UM design pattern... 1 3 Preferences UM Pattern (VB.NET)... 2 1 Introduction This document presents an implementation-oriented design pattern and the respective programming pattern developed in VB.NET for the Preferences usability mechanism (UM). 2 Preferences UM design pattern This is a design pattern for implementing the Preferences usability mechanism. The Solution section details the responsibilities that the usability functionality has to fulfil. The Structure section contains the proposed design and the Implementation section describes the steps necessary for codifying the proposed design. NAME PROBLEM CONTEXT Preferences UM Implement the Preferences um pattern for web applications so that some application features can be tailored to user preferences. Highly complex, interactive web applications for use by users with different skills, cultures and tastes. SOLUTION Components are required to fulfil the responsibilities associated with the UM. They are: A persistence mechanism for the preference types that can be set in the application, for example, language, fonts (family and size), color and so on. A persistence mechanism for the preferences that save the different combinations of preferences types: basic configuration, default settings and user custom settings. A component that allows to applied a set of preferences to the application in any time. Adapt application pages in order to define dinamically its style file.css using the PreferencesCSS class, in this way the configuration values will be always applied when the page is loaded. A component to show to the user his o her current preferences configuration and allow change its values. A component that allows seen the set of established configurations and that the user can choice one of them in order to change the current configuration. A component to that the user can change the current language of the application.
STRUCTURE IMPLEMENTATIÓN 1. Create a persistence mechanism for the information on configurable application preference types. The information to be stored by this component is: id (mechanism type identifier) and name. A means of data object access should be created for querying, creating, deleting and updating this information. 2. Create a persistence mechanism for the information on basic, predefined or personalized preferences sets. There must be a means of data object access for querying, creating, deleting and updating this information. The information to be updated by this component is: id_set (preference set identifier), id_preference_type (configurable feature identifier), name (name of the preference type attribute, if any), is_default (specifies whether the configuration is predefined), and value (the value of the configuration). 3. Implement a PreferencesCSS class that is able to generate the application style sheet dynamically by reading the configuration parameters. In the load pages call the PreferencesCSS class with the user configuration id in order to create the style file.css and the style can be applied to the page Create a page that displays the current preferences settings so that users can change their values. 4. Create a page that displays all the predefined preferences settings to be selected by users to change their current settings. 5. Create options (always visible) in order to change the application language at application level. The properties or resource files containing the translations of titles and labels to the target languages must be created beforehand. RELATED Facade pattern and MVC pattern. PATTERNS 3 Preferences UM Pattern (VB.NET) Programming patterns specify the details of the implementation using a specific language. They offer either a standalone solution or describe how to implement particular aspects of the 2
components of a design pattern using the programming language features and potential. The Solution section describes the steps necessary for codification and is equivalent to the Implementation section of the design pattern. The Structure section shows the design tailored for the VB.NET language and the Example section shows the VB.NET code for each step of the solution. NAME PROBLEM CONTEXT Preferences UM (VB.NET) Implement the Preferences UM pattern for web applications built in VB.NET with JQuery so that some application features can be tailored to user preferences. Highly complex, interactive web applications for use by users with different skills, cultures and tastes. SOLUTION 1. Create a persistence mechanism for the information on configurable application preference types. The information to be stored by this component is: id (mechanism type identifier) and name. A means of data object access should be created for querying, creating, deleting and updating this information. 2. Create a persistence mechanism for the information on basic, predefined or personalized preferences sets. There must be a means of data object access for querying, creating, deleting and updating this information. The information to be updated by this component is: id_set (preference set identifier), id_preference_type (configurable feature identifier), name (name of the preference type attribute, if any), is_default (specifies whether the configuration is predefined), and value (the value of the configuration). 3. Implement a PreferencesCSS class that is able to generate the application style sheet dynamically by reading the configuration parameters. In the load pages call the PreferencesCSS class with the user configuration id in order to create the style file.css and the style can be applied to the page Create a page that displays the current preferences settings so that users can change their values. 4. Create a page that displays all the predefined preferences settings to be selected by users to change their current settings. 5. Create options (always visible) in order to change the application language at application level. The properties or resource files containing the translations of titles and labels to the target languages must be created beforehand. ESTRUCTURA EXAMPLE 1. Create a persistence mechanism for the information on configurable application preference types. The information to be stored by this component is: id (mechanism type identifier) and name. A means of data object access should be created for querying, creating, deleting and updating this information. 3
Crear una tabla en la base de datos Preference_type, con los campos id, name. Esta tabla permitirá agregar nuevas opciones de configuración cuando se requieran, para ese ejemplo los valores definidos son: preference_type id name 1 Language 2 Font 3 Scheme 4 Sound 5 Object 2. Create a persistence mechanism for the information on basic, predefined or personalized preferences sets. There must be a means of data object access for querying, creating, deleting and updating this information. 2.1 Primero se debe crear una tabla en la base de datos Preference, con los campos indicados: id_set (identificador del conjunto de preferencias), id_preference_type(identificador de la característica a configurar), name (nombre del atributo del tipo de preferencia, si existe), is_default (indica si es una configuración predefinida), y value (el valor de configuración). preference id id_set id_preference_type name is_default value 1 0 1 name -1 en-us 2 0 2 family -1 Colibri 3 0 2 size -1 1.2em 4 0 3 theme -1 Blue 5 0 4 enable -1 true 6 0 4 wav -1 fichero.wav 7 0 5 icon1-1 1.jpg 8 1 1 name -1 es-es 9 1 2 family -1 Verdana 10 1 2 size -1 1.5 11 1 3 theme -1 Green 12 1 4 enable -1 true 13 1 4 wav -1 fichero.wav 14 1 5 icon1-1 1.jpg 15 2 1 name 0 es 16 2 2 family 0 Colibri 17 2 2 font 0 18 2 3 theme 0 sunny 19 2 4 enable 0 true 20 2 4 wav 0 fichero.wav 21 2 5 icon1 0 1.jpg 2.2 Crear un mecanismo para consultar, modificar y actualizar los datos de ésta 4
tabla. En este ejemplo se usan tableadapters. Pero se puede usar cualquier mecanismo de conexión a base de datos. Después de que se consultan algunos de los valores se guardan en variables de sesión para tenerlos disponibles para el usuario es el caso del id de preferencias, el idioma y el tema. Session("idioma") Session("idPreferences") Session("tema") 3. Implement a PreferencesCSS class that is able to generate the application style sheet dynamically by reading the configuratio n parameters. //Para este ejemplo se crea una pagina.aspx PreferencesCSS 1.1 A nivel visual no se tiene nada, lo que hace es generar un archivo tipo css, con los valores que se quieran dejar configurables, en este caso solo queda el Font-family y el Font-size, porque los demás valores de css se configuran en un tema que será asignado posteriormente. <%@ Page Language="VB" AutoEventWireup="false" CodeFile="PreferencesCSS.aspx.vb" Inherits="Preferences_PreferencesCSS" ContentType="text/css" %> /* DEFAULTS ----------------------------------------------------------*/ body { font-size: <%= FontSize%>; font-family: <%= Family%>; } 1.2 El codebehind asociad a la página PreferencesCSS debe leer la configuración asociada a un usuario para obtener los valores correspondientes. Los atributos son públicos para que puedan ser leídos desde el html Public FontSize As String Public Family As String Private Sub GetPreferences() Dim id As String = Session("idPreferences") If id = "" Then id = "0" 'Dim dataset As DataSetPreferences = New DataSetPreferences() Dim preferenceset As PreferenceTableAdapter = New PreferenceTableAdapter() Dim table As DataSetPreferences.preferenceDataTable = preferenceset.getdatabyidset(id) 5
Next For i = 0 To table.rows.count - 1 Select Case table.rows(i)("id_preference_type") Case 1 Session("idioma") = table.rows(i)("value") Case 2 If table.rows(i)("name") = "size" Then FontSize = table.rows(i)("value") Else Family = table.rows(i)("value") End If Case 3 Session("tema") = table.rows(i)("value") End Select 1.3 Cuando se carga la página PreferencesCSS lo importante es definir que va a devolver un archivo tipos css Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Page.Response.ContentType = "text/css" GetPreferences() 1.4 En el encabezado de cada página se debe llamar al PreferencesCSS, o si se tiene una máster page en su encabezado. <link href="~/preferences/preferencescss.aspx" rel="stylesheet" type="text/css" /> 4. Create a page that displays the current preferences settings so that users can change their values. Se crea un página en la que el usuario pueda cambiar sus valores. Para que los valores se actualicen se debe recargar la página. Para el caso de los temas, se deben mostrar solo los temas disponibles que estarán creados en la carpeta App_Themes. Para consultarlos y poder mostrarlos a los usuarios en un dropdownlist se usa el siguiente código: DropDownListTema.AutoPostBack = True Dim nombretemas() As String Dim directorio As DirectoryInfo nombretemas = Directory.GetDirectories(Server.MapPath("../App_Themes")) For i = 0 To nombretemas.length - 1 directorio = New DirectoryInfo(nombretemas(i)) nombretemas(i) = directorio.name Next DropDownListTema.DataSource = nombretemas DropDownListTema.DataBind() DropDownListTema.SelectedValue = Page.Theme Cuando se cambie el tema se debe actualizar el valor, y éste solo se aplicará si se coloca en el evento PreInit de la página Me.Page.Theme = Session("tema") 5. Create a page that displays all the predefined preferences settings to be selected by users to change their current settings. Para saber si una configuración es predefinida se usa el campo is_default de la tabla Preferences, la consideración a tener en cuenta es que cuando se vaya a actualizar el valor de una preferencia, si el conjunto asociado al usuario es un conjunto predefinidos, se creará uno nuevo, para no modificar los valores de las configuraciones por defecto. Si se crea un nuevo conjunto de preferencias, no olvidar actualizar la variable de sesión y la información asociada al usuario. Private Sub SetPreference(ByVal idset As Integer, ByVal idpreferencetype As Integer, ByVal name As String, ByVal value As String) 6
'Antes de salvar un cambio sobre una configuración se verifica si la actual es una configuración por defecto 'si es así se crea una nueva configuración copiando todos los valores de la actual 'si no es por defecto solo se cambia el valor que se quiera Dim idnewset As Integer Dim preferencetableadapter As preferencetableadapter = New preferencetableadapter() Dim tablepreferences As DataSetPreferences.preferenceDataTable = preferencetableadapter.getdatabyidset(session("idpreferences")) If tablepreferences.rows(0)("is_default") = True Then 'Se crea una nueva configuración para asignar al usuario, con los valores de la de por defecto menos el que cambia 'Se debe extraer cuál sería el siguiente conjunto de preferencias a crear idnewset = preferencetableadapter.getmaxidset + 1 For i = 0 To tablepreferences.rows.count - 1 preferencetableadapter.insert(idnewset, tablepreferences.rows(i)("id_preference_type"), tablepreferences.rows(i)("name"), 0, tablepreferences.rows(i)("value")) Next 'Actualiza la variable de sesión con el nuevo valor y debe actualizarse la informción del usuario Session("idPreferences") = idnewset idset = idnewset End If 'Por último se actualiza el valor que se esta cambiando Dim table As DataSetPreferences.preferenceDataTable = preferencetableadapter.getpreference(idset, idpreferencetype, name) Dim row As DataSetPreferences.preferenceRow = table.rows(0) row.value = value preferencetableadapter.update(row) 6. Create options (always visible) in order to change the application language at application level. The properties or resource files containing the translations of titles and labels to the target languages must be created beforehand. 6.1 Para que se pueda cambiar la configuración de las páginas dinámicamente es necesario sobreescribir el método InicializeCulture() Protected Overrides Sub InitializeCulture() If Session("idioma") <> Nothing Then Dim selectedlanguage As String = Session("idioma") UICulture = selectedlanguage Culture = selectedlanguage Thread.CurrentThread.CurrentCulture = _ CultureInfo.CreateSpecificCulture(selectedLanguage) Thread.CurrentThread.CurrentUICulture = New _ CultureInfo(selectedLanguage) End If 6.2 Para que se apliquen los cambios de inmediato es necesario recargar la página. Y no olvidar actualizar el valor de la variable de sesión 7