Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LiveBinding value can not be set by code

There is a TToolbar, which has it's value bound to a TText.Text.
If I change the TToolbar value, the TText.Text is changed as well. So far everything works ok.
If I set the TToolbar value manual, the Binding does not affect: The TToolbar value changes, but the Text does not.

Is there a way to trigger the LiveBinding by code?

Of course I can set the TToolbar.Value and TLabel.Text separately manual, as decommented in the code below, but this would mean
- prone to failure due redundant code in setting the Label1.Text
- not very comfortable on more complex LiveBinding situations

Sample Delphi FMX Code:

    unit Unit1;

    interface

    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 
      FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, Data.Bind.EngExt, Fmx.Bind.DBEngExt,
      System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.Components, FMX.Objects;

    type
      TForm1 = class(TForm)
        TrackBar1: TTrackBar;
        Text1: TText;
        Button1: TButton;
        BindingsList1: TBindingsList;
        LinkControlToPropertyText: TLinkControlToProperty;
        procedure Button1Click(Sender: TObject);
      private
      public
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.fmx}

    procedure TForm1.Button1Click(Sender: TObject);
    begin
      TrackBar1.Value := 11;
      // bad workaround:
      // Text1.Text := Format('%n',[TrackBar1.Value]);
    end;

    end.

According Unit1.FMX:

    object Form1: TForm1
      Left = 0
      Top = 0
      Caption = 'Form1'
      ClientHeight = 480
      ClientWidth = 640
      FormFactor.Width = 320
      FormFactor.Height = 480
      FormFactor.Devices = [Desktop, iPhone, iPad]
      DesignerMobile = False
      DesignerWidth = 0
      DesignerHeight = 0
      DesignerDeviceName = ''
      DesignerOrientation = 0
      DesignerOSVersion = ''
      object TrackBar1: TTrackBar
        Frequency = 1.000000000000000000
        Height = 20.000000000000000000
        Orientation = Horizontal
        Position.X = 32.000000000000000000
        Position.Y = 64.000000000000000000
        TabOrder = 1
        Width = 100.000000000000000000
      end
      object Text1: TText
        Height = 25.000000000000000000
        Position.X = 152.000000000000000000
        Position.Y = 64.000000000000000000
        Width = 137.000000000000000000
      end
      object Button1: TButton
        Height = 22.000000000000000000
        Position.X = 32.000000000000000000
        Position.Y = 96.000000000000000000
        TabOrder = 3
        Text = 'Button1'
        Width = 80.000000000000000000
        OnClick = Button1Click
      end
      object BindingsList1: TBindingsList
        Methods = <>
        OutputConverters = <>
        Left = 20
        Top = 5
        object LinkControlToPropertyText: TLinkControlToProperty
          Category = 'Schnelle Bindungen'
          Control = TrackBar1
          Track = False
          Component = Text1
          ComponentProperty = 'Text'
        end
      end
    end
like image 973
BitBumper Avatar asked Dec 25 '22 06:12

BitBumper


1 Answers

Unfortunately due to the design the bindings are not triggered by the setter of the Value property but by the GUI interaction (mouse clicks or key presses).

You can see that by adding an OnAssigningValue event handler to your TLinkControlToProperty binding and then looking at the callstack when it triggers.

To manually trigger this you need to write:

TBindings.Notify(TrackBar1, 'Value');

For that you have to add System.Bindings.Helper to your uses.

Edit: It seems that the bindings you can create with visual livebindings don't work with manual notification (how consistent...) and you have to use another approach:

TLinkObservers.ControlChanged(TrackBar1);      
like image 53
Stefan Glienke Avatar answered Dec 28 '22 22:12

Stefan Glienke