20 Nov 2010
Escenario: una aplicación .NET ejecutándose en una máquina de 64 bits, que falla. Exactamente el mismo ejecutable, sobre una máquina de un compañero en 32 bits, funciona perfectamente. ¿Podemos forzar a esa aplicación a ejecutarse con compatibilidad 32 bits, como hacen montones de aplicación hoy en día en los entornos de 64 (me viene a la cabeza Visual Studio 2010, por ejemplo). Claramente, sí.
Después de un poco de investigación, encontré este enlace describiendo las distintas posibilidades que tenemos. Voy a explicar cuál es la que aplicaba a mi escenario.
Modificar flag en Assembly
En mi caso, dado que era un compilado ya desplegado (fuera la opción VS) y que era una aplicación de escritorio (fuera la opción de IIS), me quedé con la posibilidad de modificar un flag del assembly.
En cada assembly existen unas ciertas cabeceras que son modificables mediante la herramienta “CoreFlags”. En este caso concreto, es el flag 32BIT el que tenemos que modificar. Para hacer el cambio, abriríamos una consola de Visual Studio y ejecutaríamos el siguiente comando, para marcar el flag y asegurarnos de que nuestra aplicación se ejecuta sobre 32 bits
CorFlags Assembly_a_modificar.exe /32BIT+
Para desactivar el flag, el comando es casi idéntico.
CorFlags Assembly_a_modificar.exe /32BIT-
Espero que os resulte tan útil como a mí.
03 Nov 2010
En estos días me encuentro inmerso en un proyecto con Silverlight. Uno de los últimos problemas que me he encontrado involucraba el siguiente escenario:
- Control cuya visibilidad está enlazado a una propiedad de un objeto (en este caso, un campo del Content de un NavigationFrame)
- Este frame, en un primer momento, tiene null en esta propiedad Content, hasta que navega.
El problema es que esta navegación se producía un instante después de que el control se creara, por lo que durante ese instante, el binding fallaba y la propiedad de visibilidad se establecía a Visible, que supongo que es el valor por defecto. Después de darle muchas vueltas encontré estas dos propiedades interesantes para este tipo de escenarios.
FallbackValue
Nos sirve para establecer un valor para el binding, cuando el binding no es capaz de resolverse y obtener un valor. Por ejemplo, en mi escenario, hasta que el NavigationFrame no navegaba por primera vez a alguna pantalla, su Content era null. Al estar mi binding enlazado a una de las propiedades del objeto que esperaba encontrar en Content, y ser éste un null, internamente el Binding estaba fallando con NullReferenceException.
Para esta situación de fallo, FallbackValue es perfecta. Básicamente estás diciéndole al binding: “si no eres capaz de calcular un valor, ponme éste directamente”.
TargetNullValue
Esta otra propiedad nos ayuda en otro escenario típico: el valor al que estamos enlazando, es null. Si por ejemplo la visibilidad de nuestro control dependiera de una propiedad string con valores “VISIBLE” y “NOVISIBLE”, podríamos crear un sencillo conversor que se encargara de devolver Visibility.Visible para el primer valor, y Visibility.Collapsed para el segundo.
¿Qué pasaría si la propiedad string contuviera un null? En tal caso, podríamos o bien modificar nuestro conversor para devolver Visibility.Collapsed también con un valor null. Pero, ¿y si no hemos creado ningún conversor? ¿No es un poco tedioso tener que crear uno sólo para gestionar los valores null?
Para eso precisamente existe TargetNullValue, que nos permite indicarle al Binding qué valor por defecto queremos que se asigne a la propiedad bindeada, en caso de que el origen del binding (source) tenga un valor null.
Espero que le resulte útil a alguien. A mí ya me hizo perder una hora y pico…
Bibliografía
MSDN: BindingBase.FallbackValue
MSDN: BindingBase.TargetNullValue
27 Oct 2010
Me ha llegado un email de la gente de Microsoft comentando que van a ofrecer en directo en sus oficinas el PDC, via streaming. El evento es los días 28 y 29 de Septiembre, a partir de las 18:00 (hora peninsular).
Entre las actividades que han programado, aparte de presenciar el evento, tenemos esto:
- Video streaming en directo y bajo demanda se presentará en alta resolución (720p) utilizando la tecnología Smooth Streaming de Silverlight.
- Vista en doble pantalla del ponente y de los demos/códigos presentados, con SCREEN PINNING y la posibilidad de etiquetar y marcar como favorito al contenido video.
- Audio traducido y subtítulos en inglés, también en directo.
- Interacción online – Clientes Twitter, un sondeo en tiempo real y una sesión de Q&A en directo con los responsables de producto y expertos.
El registro para asistir a esta sesión presencial en Microsoft, aquí.
Para los que prefieren verlo tirados desde casa, podéis acceder online desde aquí.
Y para los que se les olvida todo y luego se arrepienten, sabed que las sesiones quedarán grabadas y podréis disfrutarlas “asíncronamente” cuando os apetezca.
¿Qué es el PDC?
¿Cómo, que no sabes lo que es el PDC? Pues según dice Microsoft…
Desde 1991, la Conferencia de Desarrolladores Profesionales (PDC) ha sido el epicentro de los anuncios más importantes acerca del futuro de la plataforma de Microsoft. Sus sesiones son de un alto nivel técnico, y facilitadas por líderes y equipos que han creado y desarrollado estas mismas tecnologías. Si eres un desarrollador o arquitecto con mucha experiencia, o un líder en el sector informático que toma decisiones estratégicas para su empresa u organización, no puedes perderte la PDC. Para más información visite microsoftpdc.com.
Con eso está todo dicho, ¿no? Imprescindible para estar a la última.
17 Sep 2010
Observemos la imagen que preside este post. ¿Qué podemos ver en ella? ¿Una litografía sobre personas empujando un carro con ruedas cuadradas? No, en realidad lo que vemos es un proyecto software clásico.
En la delantera tenemos al jefe de proyecto, que desconocedor de la existencia de las ruedas redondas, ha intentado idear un mecanismo para que el proyecto avance más rápidamente que si hubiera que desplazar su pesada carga a mano. Sin embargo, sus buenas intenciones se han plasmado en un EPIC FAIL de ruedas cuadradas del que, por mucho que tira, no consigue poner en marcha.
Detrás, ejerciendo un terrible esfuerzo empujando el proyecto, tenemos al grupo de sufridos desarrolladores que, más mal que bien, intentan hacer avanzar el engendro rodándolo sobre esas ruedas cuadradas que tan desacertadamente ha diseñado el jefe de proyecto.
Si quieres evitar ser víctima de semejante estampa, vente al evento de Madrid.NET el próximo jueves 23 de Septiembre. La idea es tener un coloquio/mesa redonda/charla distendida con gurús de la gestión de proyectos como Luis Fraile y El Bruno, al tiempo que todos aprendemos de todos y de nuestras propias ruedas cuadradas.
El link para registrarse es éste: https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032462873&Culture=es-ES
Nos vemos allí.
13 Aug 2010
No descubro nada si digo que Silverlight tiene un magnífico sistema de binding, con el que nos podemos ahorrar muchísimo “code behind”. Sin embargo, me he encontrado un extraño comportamiento cuando se combina con propiedades nulables, como serían int?. Mi escenario era el siguiente:
- Un textbox bindeado a una propiedad int? en una entidad que era el data context de mi control
- Un botón que, al pulsarlo, lanzaba de forma manual el checkeo de los bindings de todos los textboxs, incluido el anterior (método UpdateSource del binding)
- Todos los métodos set de las propiedades son correctamente invocados, menos el de mi propiedad nulable.
¿Por qué? Además, como corolario, todos aquellos que no estaban correctamente formateados, se marcaban con el correspondiente borde rojo, incluido el que aparentemente no había llegado a checkearse. Y por si esto no fuera suficiente misterio, el mensaje que acompañaba al borde rojo, aparentemente había salido de ninguna parte; yo no lo había definido.
MISTERIO DESENTREAÑADO
Después de buscar bastante por Internet, llegué a esta página en la que explicaban el porqué de la situación. Al parecer, los bindings de Silverlight no se actualizan cuando no son capaces de deducir si el valor del control, es “casteable” a la propiedad que se está intentando asignar.
En mi caso, el textbox, al estar vacío, provocaba que el binding no supiera convertir un string.Empty a un int?, algo lógico por otra parte. De ahí que el método set de la propiedad nunca llegara a llamarse. La última pieza del misterio, el mensaje salido de la nada, era responsabilidad del propio binding, avisando de que no es capaz de hacer la conversión.
La solución
Ahora que ya sabemos el porqué, lo mejor es saber cómo resolverlo. Es fácil, necesitamos que “algo” convierta los valores que el binding no va a ser capaz de resolver, a valores que sí sean asignables a nuestras propiedades nulables. Por ejemplo, que cada string.Empty o puñado de caracteres vacíos, se conviertan en un null, algo con lo que el binding sí va a poder manejarse y setear en nuestra propiedades. En definitiva, necesitamos un Converter. Un ejemplo de uno totalmente funcional lo tenéis a continuación:
/// <summary>
/// Class that converts a value from an UI control to a nullable property value.
/// </summary>
/// <remarks>This class intents to resolve a "gap" in the Silverlight binding model.
/// Currently, the binding model is not able to invoke the setter of a nullable property, if
/// the value inside the control is empty.
/// Silverlight binding mechanism always avoids to invoke a setter if it is not sure how to
/// represent the type of the property to which is binded. For example, in a textbox with an empty
/// value for Text property, it will not set this value to a int? property in the underlying model.
/// </remarks>
public class NullableValueConverter : IValueConverter
{
#region IValueConverter Members
/// <summary>
/// Converts a value from the underlying entity into its UI control representation.
/// </summary>
/// <param name="value">Value to convert.</param>
/// <param name="targetType">Target type.</param>
/// <param name="parameter">Conversion parameter.</param>
/// <param name="culture">Culture to use in the conversion.</param>
/// <returns>Object converted.</returns>
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
/// <summary>
/// Converts a value from a UI control to its representation in the underlying entity.
/// </summary>
/// <param name="value">Value to convert.</param>
/// <param name="targetType">Target type.</param>
/// <param name="parameter">Conversion parameter.</param>
/// <param name="culture">Culture to use in the conversion.</param>
/// <returns>Object converted.</returns>
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string castedValue = (string)value;
if (string.IsNullOrEmpty(castedValue) == true || castedValue.Trim().Length == 0)
{
return null;
}
return value;
}
#endregion
}
Y ya lo único que nos faltaría sería utilizarlo en nuestro código XAML, en dos pasos. El primero, definirlo como recurso dentro del XAML en que vamos a usarlo:
<UserControl.Resources>
<controls:NullableValueConverter x:Key="NullableValueConverter"/>
</UserControl.Resources>
Y el segundo, asociándolo al binding que hemos establecido entre el control y la propiedad nulable.
Text="{Binding MyNullableProperty, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, Converter={StaticResource NullableValueConverter}}"
Y esto es todo. Espero que os sea de utilidad.