Jump to content

Recommended Posts

Posted

Here is the way to make TUniEdit observable by LiveBindings :

unit UniObservableEdit;

interface

uses
  System.SysUtils, System.Classes, Vcl.Controls, uniGUIBaseClasses,
  uniGUIClasses, uniEdit,
  WinApi.Messages, WinApi.CommCtrl,
  Data.Bind.Components;

type
  [ObservableMember('Text')]                            { identifies the control value name for TUniObservableEdit }

  TUniObservableEdit = class(TUniEdit)
  private
    procedure ObserverToggle(const AObserver: IObserver; const Value: Boolean);
    procedure DoSetRemoteValue(AIndex:Integer;Value:String);override;
  protected
    function CanObserve(const ID: Integer): Boolean; override;                       { declaration is in System.Classes }
    procedure ObserverAdded(const ID: Integer; const Observer: IObserver);  override; { declaration is in System.Classes }
  public
  published
  end;

procedure Register;

implementation


function TUniObservableEdit.CanObserve(const ID: Integer): Boolean;
{ Controls which implement observers always override TComponent.CanObserve(const ID: Integer). }
{ This method identifies the type of observers supported by TUniObservableEdit. }
begin
  case ID of
    TObserverMapping.EditLinkID,      { EditLinkID is the observer that is used for control-to-field links }
    TObserverMapping.ControlValueID:
      Result := True;
  else
    Result := False;
  end;
end;

{ The override for DoSetRemoteValue is where TUniObservableEdit calls the
  observable interfaces to notify LiveBindings components when the user types something.
  This override is sufficient to monitor user input to TUniObservableEdit.
  TLinkObservers.ControlChanged is a utility method that does most of the work. You can
  find the implementation in System.Classes. }

procedure TUniObservableEdit.DoSetRemoteValue(AIndex:Integer;Value:String);
begin
  inherited;
  TLinkObservers.ControlChanged(Self);
end;

procedure TUniObservableEdit.ObserverAdded(const ID: Integer;
  const Observer: IObserver);
begin
  inherited;
  if ID = TObserverMapping.EditLinkID then
    Observer.OnObserverToggle := ObserverToggle;
end;

procedure TUniObservableEdit.ObserverToggle(const AObserver: IObserver;
  const Value: Boolean);
var
  LEditLinkObserver: IEditLinkObserver;
begin
  if Value then
  begin
    if Supports(AObserver, IEditLinkObserver, LEditLinkObserver) then
      { disable the uniEdit if the associated field does not support editing }
      Enabled := not LEditLinkObserver.IsReadOnly;
  end else
    Enabled := True;
end;

procedure Register;
begin
  RegisterComponents('uniObservableComponents', [TUniObservableEdit]);
end;

initialization
  Data.Bind.Components.RegisterObservableMember(TArray<TClass>.Create(TUniObservableEdit), 'Text', 'DFM');

finalization
  Data.Bind.Components.UnregisterObservableMember(TArray<TClass>.Create(TUniObservableEdit));
end.
  • Like 1
  • Upvote 2
  • 4 months later...
Posted

Hi Bresler,

 

Actually, my previous post was the example ;)

 

You just have to create a new component (as usual in Delphi) and put my code in the unit of your component.

Then you can use this component with LiveBindings as any VCL or FM component.

  • Upvote 1
Posted

Hi Bresler,

 

I asked the same question to Jim Tierney, the creator of LiveBindings at Embarcadero.

Here is his answer :


Hi Renaud, 

In general, you will need to find the code that is used to implement LiveBindings (LB) support for VCL TStringGrid and implement similar code for your component.

1.  Column manager (adds columns, defines expressions)

Copy VCL.Bind.Grid.pas  to a new unit and modify to work with your grid.  

2.  Editor (adds rows)

Copy Vcl.Bind.Editors.TBindListStringGridEditor to another unit and modify to work with your grid.

3.  Observers (process user input)

Look in Vcl.Grids to see where observers are called for TStringGrid.  Implement similar code in your grid.

Implementation of 1, 2  and TYourGrid.CanObserve should be enough for LB to populate your grid.  You will need complete observer implementation to support editing and navigation.

Note that there is code in LB to try to tell the difference between a TStringGrid with one row and a TStringGrid that is empty.  TStringGrid does not make a clear distinction.  You may not need this code if your grid makes a clear distinction between empty vs. only one row.  

Let me know if you have any questions about the code to implement LB for TStringGrid.  

Jim

Unfortunately, I didn't achieve to make a "TUniObservableStringGrid" despite his explanations.

 

Maybe you'll be luckier than me...  

 

BTW: if you create an observable TUniStringGrid with success, please share your code ;)

 

Good luck.

Posted

Hi Bresler,

 

Sorry for this late answer: I have currently a lot of work, I will take a look at your code this week-end. 

×
×
  • Create New...