ZigZig Posted January 29, 2014 Posted January 29, 2014 Hi, Is it possible to make uniGUI components suitable with LiveBindings (see this article : http://blogs.embarcadero.com/jimtierney/2012/10/01/31653/#link2) ? There is currently no observer for those components, so LiveBindings cannot observe a TUniEdit component (for example). Thanks a lot !
ZigZig Posted February 4, 2014 Author Posted February 4, 2014 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. 1 2
Bresler Posted June 4, 2014 Posted June 4, 2014 Hi Zigzig, how to use this solution? Can you share any example about it??? Thanks
ZigZig Posted June 4, 2014 Author Posted June 4, 2014 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. 1
Bresler Posted June 6, 2014 Posted June 6, 2014 Hi Zigzig, I tested the code below and it works... But any idea how could by it with the TUniStringGrid?
ZigZig Posted June 7, 2014 Author Posted June 7, 2014 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.
Bresler Posted June 9, 2014 Posted June 9, 2014 Ok... lets try... This is the most important component and the most complex too...
Bresler Posted June 9, 2014 Posted June 9, 2014 Hi ZigZig... I follow the steps below and implemented the component... But unsuccessfully...
Bresler Posted June 9, 2014 Posted June 9, 2014 Here is the code... Take a look... TBLUStringGrid.rar
ZigZig Posted June 13, 2014 Author Posted June 13, 2014 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.
Recommended Posts