Search code examples
delphilivebindingsspring4d

Nullable scalar types and LiveBindings


I want to bind a TObjectList of custom delphi objects to a grid using live bindings. I wish to have Nullable support for the object properties so that if they do not have a value, they show up blank in the grid and edits similar to how datasets work with nullable db columns.

I'm assuiming the Delphi language doesn't have support for nullable types?

TMyObject = class
private
    FQuanitity: Nullable<Integer>;
    FDescription: Nullable<string>;
public
    property Quantity: Nullable<Integer> read FQuanitity write FQuanitity;
    property Description: Nullable<string> read FDescription write FDescription;
end;

FMyObectList: TObjectList<TMyObject>;

I would create a TPrototypeBindSource and bind FMyObjectList using the OnCreateAdapeter

Can someone point me in the right direction for how to do something like this? Thanks

EDIT / Answer:

The best option for Nullable types is Spring4D, but there is no way to directly bind these values using Live bindings.


Solution

  • Here is how you register the type conversion for Nullable<string> to string and vice versa in the LiveBindings engine:

    procedure RegisterNullableConversions;
    begin
      TValueRefConverterFactory.UnRegisterConversion(TypeInfo(Nullable<string>), TypeInfo(string));
      TValueRefConverterFactory.RegisterConversion(TypeInfo(Nullable<string>), TypeInfo(string),
        TConverterDescription.Create(
          procedure(const I: TValue; var O: TValue)
          begin
            if I.AsType<Nullable<string>>.HasValue then
              O := I.AsType<Nullable<string>>.Value
            else
              O := 'null';
          end,
          'NullableToString', 'NullableToString', EmptyStr, True, EmptyStr, nil)
      );
      TValueRefConverterFactory.UnRegisterConversion(TypeInfo(string), TypeInfo(Nullable<string>));
      TValueRefConverterFactory.RegisterConversion(TypeInfo(string), TypeInfo(Nullable<string>),
        TConverterDescription.Create(
          procedure(const I: TValue; var O: TValue)
          begin
            O := TValue.From<Nullable<string>>(I.AsString);
          end,
          'StringToNullable', 'StringToNullable', EmptyStr, True, EmptyStr, nil)
      );
    end;