¿Juega usted a la Bolsa?… Yo tampoco

A medida que pasa el tiempo le va confiriendo uno menos importancia a lo que piensen los demás sobre defectos, deficiencias e ignorancias que se acarrean. Una de ellas es la del juego de la bolsa, es decir, el juego del dinero. Desde pequeños, acostumbrados a la carestía de los alimentos y su escasez, nuestros padres nos recomendaban con signos de rigor prohibitivo que no se jugase con las cosas de comer, a las que se daba cierto carácter sacro, en especial al pan. Si se caía un trozo al suelo, se le besaba como pidiéndole perdón, y al ser partido por el padre o la madre en la mesa, trazaban con la punta del cuchillo en el envés una señal de la cruz con la que lo convertían en el objeto sagrado que había costado el sudor de la frente, tal como preconizaba el precepto bíblico. Si el pan era sagrado no había de serlo menos el elemento necesario para comprarlo: el dinero, el salario obtenido con dureza por el trabajador, administrado minuciosamente para alimentar a la familia durante todo el mes. A nadie en su sano juicio se le ocurriría jugar con él, salvo que estuviese fuera de sus casillas o, por la razón que fuere, le sobrase y, contraviniendo cualquier recomendación bíblica o evangélica, se dedicase a apostar la manera de perderlo o de ganar mucho más sin esfuerzo alguno para él.

En España no pasará de un cinco por ciento la cifra de afortunados que pueden dedicarse a este deporte que tiene su cancha en un palacio de la plaza de la Lealtad de Madrid. Este divertido juego, en el que es corriente hundir un buque lleno de plátanos para equilibrar el mercado, o hacer desaparecer toda la especie del atún rojo para elevar el precio del stock congelado, es el que se permiten desarrollar unos pocos miles de personas que no tienen la menor idea de lo que es coger un pico, poner un ladrillo, trabajar en un taller de confección bajar a la mina, subir a un tractor o cumplir una jornada laborar completa en una tienda. Estos ciudadanos, para los que el dinero no es una necesidad, sino una diversión, son los que deciden cuál ha de ser su sueldo, el coche que pueden comprar, el crédito al que pueden acceder, el grado de cobertura de su sistema sanitario, la calidad de la enseñanza de sus hijos, y muchas cosas más. Ellos deciden lo que le costará la gasolina, el pan, la carne, las vacaciones y hasta los gastos de su entierro. Y usted, amigo mío, amiga mía, no tiene otra opción que pagar y callar. Le dicen que es libre porque puede elegir cada cuatro años al grupo político que mejor cree representarle, pero nunca le dicen que, sea cual sea, quien va a gobernar es ese cinco por ciento que juega con el dinero sin importarle que todo pueda irse a la mierda. Es el juego. Es la nueva religión, que ya tiene más de un centenar de años: el capitalismo.

Hoy en día, para que una cosa parezca menos mala, le ponen al lado la palabra “libre”, y en vez de capitalismo le llaman “libre mercado”. Pero es lo mismo. Todo es mucho más barato y mejor cuando es privado, hasta el ejército. A esto le llaman “externalizar servicios”. El objetivo y el esfuerzo de unos que mandan, unido a la complicidad de quienes dicen estar en la oposición, es crecer de manera capitalista, aun a costa de saber a ciencia cierta que cada punto de crecimiento supone la emisión de varios miles de toneladas más de contaminación a la atmósfera. Fuera del capitalismo no hay salvación, dicen quienes lo equiparan a la Iglesia Católica en un acto de crujir de huesos de su fundador.

Usted y yo, amiga mía, estamos fuera de juego. No sabemos casi nada ya de lo que dicen los periódicos y nos causa cierto estupor lo que parecen saber los que en ellos escriben. Le ahorraré la orgía de términos económicos que se han apoderado de las páginas de lo que antes eran noticias de otro cariz, pero reconózcame que sería preciso hacer un curso para estar al día si ello mereciese la pena. Ni usted ni yo tenemos credibilidad —crédito—, ni dinero —liquidez— para que se nos tenga en cuenta más que a la hora de votar. Eso sí, le aseguro que hasta los que afirman estar más cerca de los necesitados participan de ese eufemístico libre mercado que a usted y a mí nos ignora por completo, salvo que le toque la lotería y decida jugar a la bolsa.

Ante este tipo de opiniones se suele argumentar que el mundo está hecho así y que no tiene remedio, y que es demagogia cuanto se aparte de su credo. Y usted me dirá: vale, aporte soluciones. Ahí es nada, como si uno cobrase por ello. Sólo pretendía compartir con usted su ignorancia y su estupor, que ya es bastante. De ese “hazlo tú” estamos exentos quienes un día creímos y luego, viejos y acusados de utópicos, dejamos de creer. Pero, si se empeña, un día le diré lo que pienso si no se lo cuenta a nadie.

___________________________

Este artículo ha salido de la pluma de Venancio Díaz Castán, nacido en Graus (Huesca). Médico, escritor y suegro.

WPF UniformGrid vs Grid con IsSharedSizeScope = True

Lo que voy a publicar hoy es un pequeño truco que seguramente todos conozcáis, pero que sin duda puede ayudar a ahorrar mucho tiempo de diseño en vuestras preciosas y coherentes aplicaciones. Decir que los controles destinados al Layout de una interfaz de usuario en WPF son espectaculares sobra. Hay una gran cantidad de Panels que se ajustan a cualquier situción que estemos buscando. Pero a mí siempre me llaman la atención las cosas sencillas. Qué duda hay de que el Panel Grid de WPF es el más versátil de todos. Nos permite hacer cualquier cosa. Podemos definir tantas filas y columnas en él como queramos. Vamos, una pasada de control. Pues bien, uno de los “truquillos” de Grid es establecer el valor de la AttachedProperty Grid.IsSharedSizeScope a True. (De momento no hablaré de las Attached Properties, pero quizás me anime a hacerlo en un post posterior puesto que he implementado algunos trucos bastante interesantes con este mecanismo.) Dicha propiedad permite que las columnas o filas presentes en el Grid compartan entre ellas información de su anchura o altura. ¿Para qué puede ser útil? Se recurre mucho a esta técnica, por ejemplo, en el caso de querer hacer que los Button pertenecientes a un mismo grupo o categoría tengan el mismo tamaño (equivalente al máximo de entre todos). ¿Para qué se recurre a esto? Aunque todo es cuestión de diseño, hay estudios que demuestran que en una pareja de botones “Imprimir – Mandar por correo electrónico” por ejemplo, ambos deberían tener el mismo ancho para no parecer incoherentes. Siempre se puede usar un ancho fijo para ambos, pero no es una solución elegante si nuestra aplicación va a ser traducida a diversos idiomas donde las palabras, obviamente, no miden lo mismo. Para conseguir, pues, este efecto de homogeneidad se puede hacer uso de un par de columnas (ColumnDefinition), colocar en cada una de ellas un botón, establecer la propiedad SharedSizeGroup de cada ColumnDefinition a un valor común (por ejemplo “Grupo”) y el ingrediente final: la mencionada Grid.IsSharedSizeScope = True en el Grid contenedor. Veamos el XAML de dicho escenario:

 1: <Grid Grid.IsSharedSizeScope="True">
 2:     <Grid.ColumnDefinitions>
 3:         <ColumnDefinition SharedSizeGroup="Group"/>
 4:         <ColumnDefinition SharedSizeGroup="Group"/>
 5:     Grid.ColumnDefinitions>
 6:         <Button Content="Imprimir" Grid.Column="0" Margin="0,0,4,0"/>
 7:     <Button Content="Enviar por correo electrónico" Grid.Column="1" Margin="4,0,0,0"/>
 8: </Grid>

El resultado es el que esperábamos. Ambos botones tienen el mismo ancho y si en un futuro queremos cambiar el idioma o, incluso, el texto original, los botones seguirán siendo igual de anchos. Varias decenas de veces he repetido este mecanismo para diferentes situaciones, hasta que un día me percaté de que tanta “verborrea” de xaml se podría simplificar mucho haciendo uso de mi gran amigo: El sencillo UniformGrid. Con este Grid simplificado solo hay que tener en cuenta cuántas columnas y filas queremos u olvidarse por completo de definir nada (en cuyo caso UniformGrid creará dinámicamente tantas columnas como filas para que cada elemento hijo tenga cabida y se organice de una manera homogénea). Por lo tanto, para hacer una equivalencia de nuestro ejemplo pero con UniformGrid sólo necesitaremos establecer el número de filas que queremos. En nuestro caso será uno. UniformGrid se encargará pues de crear tantas columnas del mismo ancho como hijos contenga. De este modo tan sencillo y olvidándonos por completo de propiedades especiales y mágicas que necesitan trabajar juntas hemos conseguido el mismo efecto de homogeneidad en nuestros botones. Veamos el XAML necesario:

 1: <UniformGrid Rows="1">
 2:     <Button Content="Imprimir" Margin="0,0,4,0"/>
 3:     <Button Content="Enviar por correo electrónico" Margin="4,0,0,0"/>
 4: </UniformGrid> 

Mucho más sencillo y legible, ¿verdad? Y como siempre digo, esto sólo es un pequeño ejemplo, pero puede haber una gran cantidad de situaciones en las que se requiera el uso de cualquiera de estas técnicas para conseguir distintos resultados. Una de ellas, por ejemplo, es la necesidad de compartir anchuras entre diferentes items de una lista, los cuales han sido generados por un DataTemplate que contiene Grids y varias columnas. Pero quizás os lo explique en otro post. Espero no haber aburrido demasiado a nadie y gracias por leerme. Saludos

Multi-Conversor en WPF con IMultiValueConverter

A raíz de un post del blog de Javier Torrecilla y una posterior conversación en Twitter, he decidido escribir mi primera entrada.

Hablaré un poco sobre cómo implementar la interfaz  System.Windows.Data.IMultiValueConverter y propondré un ejemplo, a mi parecer, divertido.

La interfaz IMultiValueConverter contiene dos métodos, Convert y ConvertBack, al igual que en IValueConverter. A diferencia de como ocurre en ésta, Convert recibe en su primer parámetro un array de object. Es por ello que ya no estamos ante un Converter normal y corriente que transforma un objeto en otro, sino que tenemos la posibilidad de pasarle a dicha función tantos objetos como queramos, los cuales serán posteriormente utilizados para crear el valor resultado.

Veamos el ejemplo:

Código del multi-conversor:

 1: using System.Windows.Data;
 2: using System;
 3: using System.Globalization;
 4: namespace IMultiValueConverterExample
 5: {
 6:    public class ChromosomeToBabyConverter : IMultiValueConverter
 7:    {
 8:       public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
 9:       {
 10:          string first = (string)values[0];
 11:          string second = (string)values[1];
 12:          if (first == second && first == "X")
 13:          {
 14:             return "Girl";
 15:          }
 16:          else if (first == "X" && second == "Y" || first == "Y" && second == "X")
 17:          {
 18:             return "Boy";
 19:          }
 20:          else
 21:          {
 22:             return "Angel";
 23:          }
 24:       }
 25:  
 26:       public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
 27:       {
 28:          if ((string)value == “Boy”)
 29:          {
 30:             return new string[] { “X”, “Y” };
 31:          }
 32:          else if ((string)value == “Girl”)
 33:          {
 34:             return new string[] { “X”, “X” };
 35:          }
 36:          else
 37:          {
 38:             return new string[] { “Y”, “Y” };
 39:          }
 40:       }
 41:    }
 42: }

 
Y ahora el marcado XAML con una sencillísima interfaz que contiene tres TextBox. (Los dos primeros permiten escribir el tipo de cromosoma y el tercero muestra el sexo del bebé)

 1: <Window x:Class="IMultiValueConverterExample.MainWindow"
 2:    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3:    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4:    Title="IMultiValueConverterExample"
 5:    xmlns:local="clr-namespace:IMultiValueConverterExample">
 6:    <StackPanel>
 7:       <StackPanel.Resources>
 8:          <local:ChromosomeToBabyConverter x:Key="converter"/>
 9:       </StackPanel.Resources>
 10:       <TextBox x:Name="first"/>
 11:       <TextBox x:Name="second"/>
 12:       <TextBox>
 13:          <TextBox.Text>
 14:             <MultiBinding Converter="{StaticResource converter}">
 15:                <Binding ElementName="first" Path="Text"/>
 16:                <Binding ElementName="second" Path="Text"/>
 17:             </MultiBinding>
 18:          </TextBox.Text>
 19:       </TextBox>
 20:    </StackPanel>
 21: </Window>

 
Espero que en éste, mi primer post, me haya explicado correctamente y con ello la gente se anime al uso de esta técnica.
¡Saludos!