Durante los próximos meses, vamos a ser muchos los compañeros que tomemos contacto con áreas nuevas de nuestro entorno de desarrollo, en esa fase de acercamiento a RadStudio XE2, como pueda ser LiveBindigns, los estilos, las capacidades gráficas 2D/3D. Y es que tenemos por delante, la difícil tarea de asimilar todas estas novedades y comprender de que forma se pueden acoplar a nuestra programación diaria, o del día a día.  Y por lo menos a mí, no me queda duda de que va a ser un proceso largo y evidentemente no trivial. Esa realidad, difícilmente se puede negar o esconder. De hecho, vamos a afrontarla a medida que requiramos funcionalidades más avanzadas y confrontemos la plataforma con las necesidades reales de los proyectos. Es entonces cuando mas echaremos en falta una buena documentación y nos veremos en la necesidad de salir a la red en búsqueda de respuestas. A diferencia de etapas anteriores,  contamos con la dificultad añadida que es la ausencia de documentación o en su defecto, la deficiente calidad de la misma. Y su juventud, que hace dificilmente comparable nuestra VCL con FireMonkey, y que se manifiesta en que todavía no exista ese banco de respuestas que nos permite contrastar si la dificultad ya ha sido enfrentada por otros compañeros.  Esa es la parte mas negativa y creo que ser realista es distinto de ser agorero, actitud en la que muchos van a caer, en ese discurso fácil y destructivo.

Resaltemos también las cosas buenas: En lo positivo, está el hecho reconocido y valorado por muchos compañeros, entre ellos yo, de que Embarcadero conoce esto, es consciente de ello, -el primer paso para solucionarlo- y está haciendo un verdadero esfuerzo por dotar a la nueva plataforma de actualizaciones, que corrijan los errores que van siendo detectados y por supuesto, de nuevos ejemplos que puedan ayudar mitigando o aliviando la falta de documentación.

Estos días anteriores hemos conocido la disponibilidad de la cuarta actualización de RadStudio XE2. ¡La cuarta…! Es una prueba evidente de esa voluntad de hacer las cosas bien, que argumentaba en lineas anteriores. Nosotros siempre preferimos ver el vaso medio lleno antes que medio vacío, por lo que, fuera de la incomoda tarea de las instalaciones y la pereza de hacerlas, prevalece la necesidad de que sean corregidos y mejorados cuantos detalles mejor.

Release Notes for XE2 Update 4

Así que leed con atención las indicaciones de instalación, que son similares a las que pudimos tener en updates anteriores.

Comentaba, siguiendo un poco lo que decía, que van siendo cada vez mas frecuentes las preguntas acerca de estas novedades, pudiendo contar con alguna que otra en el foro de Delphi Solidario.

Hoy por ejemplo, se ha dejado una pregunta en el aire sobre LiveBindings y el componente TListBox, en donde se compartía un problema al llenar la lista interna TStrings que mantiene el componente, para mostrar los distintos items de selección. La persona que hacía la pregunta mostraba que tan solo había conseguido recuperar 200 registros de una tabla que almacenaba una cantidad mayor. Y realmente creo que su problema era no saber si estaba haciendo algo no correcto o era una limitación, cosa improbable aunque difícil de adivinar si no cuentas con una buena documentación o accedes a las fuentes y ves que está sucediendo realmente. Así que tenemos también nosotros, todos los que participamos en la Comunidad, la tarea de aportar toda nuestra ayuda y os invito a volcarnos en nuestros foros y participar de ellos. No me cabe la menor duda que en unos días se resolverá ese problema, ese y los sucesivos, que van a ir apareciendo desde distintos puntos de nuestra Comunidad.

Posiblemente en unos meses también contemos ya con la publicación de los libros que están ahora escribiéndose, el de Marco Cantú (en inglés) o el de Francisco Charte (en español). O se haya añadido mas detalle a la documentación actual, fruto de un nuevo Update. Tengo confianza de que sea como sea, vamos a seguir adelante, mas si prevalece el espíritu que ha marcado siempre a nuestra Comunidad hispana.

Yo, por mi parte, -ya me conocéis- también intento poner mi granito de arena, con independencia de que no siempre podamos resolver los problemas. Siempre acaba uno aprendiendo algo en ese proceso de ayuda y eso es lo verdaderamente importante.

Hace algo mas de una semana compartía con un compañero de ecuador varios correos y me pedía algún enlace al tema de livebindings y el componente TDBLookupCombo. Ya sabéis que la nueva plataforma FireMonkey nos ha dotado de un nuevo sistema de enlace a datos, livebindings, alternativo en la VCL al tradicional uso del [control-datasource-dataset], que ya conocemos. Y mientras todavía nos es factible el uso de ambos sistemas desde la VCL, en los desarrollos ligados a firemonkey solo tenemos disponibles los controles que accedan a datos a través de la nueva tecnología. Quiere decir que ya no existen ni el TDBEdit, ni el TDBLookCombo, etc. y nos valemos de cualquier componente que pueda ser compatible o que acepte el enlace a datos. Y quien dice cualquier, dice eso precisamente…  🙂

 Creo que no somos conscientes de la increíble mejora a medio/largo plazo que eso puede suponer. Es un tema de mayor calado que nos puede ayudar en la búsqueda de mejores perspectiva de la Orientación a Objetos.

De mis pesquisas sobre el tema que se me planteaba, pude contrastar algunos detalles que posiblemente podamos compartir mas adelante con algún ejemplo. El hecho es de que el componente TComboBox no se adapta correctamente a lo que podemos demandar de un TDBLookupCombo. No porque no sea capaz de desplegar una lista que lo es, sino porque precisamente le falta lo que le hace distinto: tener una fuente de datos que provea la clave primaria o key value asociada y no el item selector. Esa es la clave del asunto y que dificultaba resolver el problema. El usuario visualiza un item de una lista de alternativas y de ese proceso de selección, lo que guardamos es una clave, cumpliendo las normas habituales de normalización de tablas, de las cuales huelga comentarios.

Os muestro una imagen que compartía con él, en ese intercambio de correo:

formulario_principal

Había preparado un formulario en el que existían 3 tablas muy básicas. Una con una lista de personas, otra con una lista de grupos y una tercera que se alimentaba de las dos y que las relacionaba, formando equipos de personas asignados a grupos.  Pero bueno… al final, que uno consiga poner un parche y simular el comportamiento del componente no es suficiente ni siempre es correcto. Y realmente, acababa las lineas de mi correo, comentándole que no me gustaba la solución y no la consideraba válida, quedando a la espera de encontrar alguna idea en la red o documentación.

Asumiendo el peligro de equivocarme, creo que ninguno de los enlaces o expresiones existentes, tal y como está ahora mismo, se adaptan al componente TComboBox de forma que se simule el comportamiento de un TDBLookupCombo, por cuanto aunque somos capaces de rellenar la lista de items, cosa que puede hacer el enlace TBindList, al que nos basta indicarle en la propiedad Text del TComboBox, y Value del campo vinculado al origen de datos, produciendo de forma automática que sea relleno cada item de la lista con los valores de la tabla, tropezaremos con el problema que los enlaces o expresiones van a intentar hacer una correspondencia directa entre el item selector y el campo destino. Si optamos en ese camino se mostraran advertencias del tipo: Vd. intenta guardar un string y esperaba un valor entero… ¡Mal camino!.

Otra alternativa, es la de optar por un TBinPosition, para conseguir sincronizar el itemindex del combo con valor actual de la clave guardada en la tabla. Aquí tambien nos encontraremos con un problema. En los ejemplos que usa Embarcadero, que se encuentran  en el directorio Samples/Livebindings (podéis hacer una búsqueda con el término del nombre del proyecto que agrupa los ejemplos: BindSamplesGroup.groupproj) hay uno que se pone en varios foros como muestra de trabajo con TListBox, similar al TComboBox en cuanto a la gestión de cadenas, y siempre se utiliza el enlace TBinPosition para resituar y sincronizar el recno de la tabla con el itemindex… El detalle está en este caso, es que el Recno no se utiliza y no es aplicable a lo que buscamos, porque lo que tiene sentido es el valor de la clave (FieldByName(‘IDGrupo’).AsInteger y no el valor de la propiedad RecNo del registro).  🙂   Y el itemindex muestra la posición del item seleccionado pero no existe una correspondencia con lo que nosotros hubieramos identificado con el keyvalue de cada item.

Así que ese camino esta también lleno de problemas y nos obliga a añadir al componente ComboBox varios enlaces a datos, uno para llenar la lista, otro para sincronizar desde el control a la fuente de datos y un tercero para enfocar el sentido contrario, desde la fuente de datos al componente. Todo demasiado complicado, en relación a lo sencillo que es el enlace que hubieramos planteado desde la plataforma VCL.  😦

Pero decía también al principio de la entrada que el hecho ayudar a alguien implica también el constante aprendizaje que uno recibe y que nos hace descubrir cosas o aspectos que en principio no esperabamos. Y digo esto porque el problema realmente no ha estado en la tecnología sino en el aprendizaje de su uso.

El motor de expresiones que se ha incorporado para sostener el corazón de LiveBindings es algo que aun está por descubrir por la Comunidad y que poco a poco va a ir siendo conocido a medida que vayamos teniendo buena documentación y aprendamos como valernos de él, en lugar de luchar contra él.

Alguien pensaría que los métodos que en tiempo de diseño nos muestra el entorno y que podemos utilizar para generar las expresiones va a ser algo inmutable y nada mas lejos de la realidad. Vamos a ver un ejemplo muy sencillo adaptado sobre los que acompañan a la unidad System.Bindings.Methods y que va a permitir que sea calculado el valor doble del introducido en un casilla cualquiera.

 

doublemethod

unit UMyMethod;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, System.Bindings.Methods,
  System.Rtti, System.TypInfo, System.Generics.Collections, System.Bindings.Evaluator,
  System.Bindings.ObjEval, System.Bindings.EvalProtocol, System.Bindings.Consts,
  FMX.Edit, Data.Bind.EngExt, Fmx.Bind.DBEngExt, System.Bindings.Outputs,
  Data.Bind.Components, Fmx.Bind.Editors;

resourcestring
  sInvalidValueError = 'Valor no aplicable a la operación';

type
  TfrmDobleValor = class(TForm)
    edValor: TEdit;
    edDobleValor: TEdit;
    lbDobleValor: TLabel;
    lbValor: TLabel;
    BindingsList1: TBindingsList;
    BindExpressionedDobleValor1: TBindExpression;
    Label1: TLabel;
    procedure edValorChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmDobleValor: TfrmDobleValor;

implementation

{$R *.fmx}

function MakeMethodDoubleValue: IInvokable;
var
  str: String;
begin
  Result := MakeInvokable(function(Args: TArray): IValue
  var
    v1: IValue;
    LExt: Extended;
  begin
    if Length(Args) <> 1 then
      raise EEvaluatorError.Create(sFormatArgError);
    v1 := Args[0];
    str:= Trim(v1.GetValue.AsString);
    //manejamos el caso de valor vacio
    if v1.GetValue.IsEmpty then
      Exit(TValueWrapper.Create(nil))
    else
    begin
       if TryStrToFloat(str, LExt) then
         Exit(TValueWrapper.Create(LExt * 2))
       else raise EEvaluatorError.Create(sInvalidValueError);
    end;
  end);
end;

const
  sIDDoubleValue = 'DoubleValue';

procedure RegisterMyMethod;
begin
  TBindingMethodsFactory.RegisterMethod(
    TMethodDescription.Create(
      MakeMethodDoubleValue,        //AInvokable:IInvokable
      sIDDoubleValue,               //AID
      sIDDoubleValue,               //AName
      '',                           //AUnitName
      True,                         //ADefaultEnabled
      '',                           //ADescription
      nil));                        //AFrameworkClass
end;

procedure UnRegisterMyMethod;
begin
   TBindingMethodsFactory.UnRegisterMethod(sIDDoubleValue);
end;

procedure TfrmDobleValor.edValorChange(Sender: TObject);
begin
 BindingsList1.Notify(edValor, 'Text');
end;

initialization
  RegisterMyMethod;

finalization
  UnRegisterMyMethod;

end.

Descargar código

La moraleja de la historia creo que se adivina: Cuando caía hace un par de días sobre dicha unidad (System.Bindings.Methods), fruto de querer resolver el problema, y podía ver como se habían generado las expresiones del editor, y realmente apreciaba la “facilidad” que existía en crearlas y usarlas, y la potencia que podía aportar, sin tener que depender de la que mostraba el editor, sino crearme las propias expresiones, me hacía también suponer que se abrían alternativas, pudiendo generar adicional mente vías para entiquecer el flujo de datos entre el componente y la fuente, que era precisamente lo que ahora pienso que me impedía resolver el problema. Posiblemente, la expresión que recorre la tabla para llenar la lista pueda adicionalmente rellenar los valores de las claves o keyvalues, por lo que no necesite mas de dos enlaces entre ellos: el que alimenta la lista de cadenas y el que hace corresponder una clave con un valor en la tabla, mostrando el texto selector.

Nada mas por hoy. Un abrazo a todos y estamos de vuelta para pelear por la Comunidad. Si hay algo que nadie puede prohibirme es seguir aprendiendo y disfrutando de ello.

Enlaces sobre el tema imprescindibles:

http://www.jcolibri.com/articles/firemonkey/livebindings_delphi_xe2/livebindings_delphi_xe2.html

http://www.danieleteti.it/2011/08/30/in-the-core-of-livebindings-expressions-of-rad-studio-xe2/

http://neftali.clubdelphi.com/?p=1783

Un comentario sobre “Mi método doble valor y expresiones con LiveBindigns

  1. Saludos,
    Me gustaria aprender a utilizar radstudio xe2 como lo es delphi dentro de este suit de studio como guias basicas o manuales como recien sale no he encontrado nada, por lo que lo he moniado por hay me gusta por la facilidad de multiplataforma y los gran cantidad de objetos y conexiones que puedes hacer a bdd!!!! es muy extenso pero me gusta aprender mucho….me ayudan con algo vale….

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s