【本文转自Blog of NeuglsWorkStudio】
为了方便解释如何在程序中使用LiveBinding, 请建立一个控制台程序。
你需要在Uses子句中添加以下几个单元:
Uses System.Bindings.Expression, System.Bindings.Helper;
要了解更多的信息,请查看相关的API说明文档:
System.Bindings.Expression (该单元里包含了绑定表达式相关的类与方法)
System.Bindings.Helper (该单元包含了绑定辅助类的一些方法)
下面你需要定义两个你需要绑在一想的绑定对象,例如我们这里定义为TMyObject1和TMyObject2两个类的实例,这两个类都有两个属性:一个是字符串类型,另一个是整数类型。
定义第一个类如下
type TMyObject1 = class(TObject) private FIntegerValue: Integer; FStringValue: String; public property IntegerValue: Integer read FIntegerValue write FIntegerValue; property StringValue: String read FStringValue write FStringValue; end;
定义第二个类
type TMyObject2 = class(TObject) private FIntegerValue: Integer; FStringValue: String; public property IntegerValue: Integer read FIntegerValue write FIntegerValue; property StringValue: String read FStringValue write FStringValue; end;
上面的代码中,你会发现,两个类基本上都是一样的,都不包含方法,构造函数与析构函数都是从System.Tobject上继承而来,你可以简单的初始化与释放他们!为了更好了说明它们,你可以查看下面的代码片段:
var MyObject1: TMyObject1; MyObject2: TMyObject2; begin MyObject1 := TMyObject1.Create; MyObject2 := TMyObject2.Create; { various binding operations - see follwing context } MyObject1.Free; MyObject2.Free; end;
第三个对象MyResultObject声明用于保存上面两个对象的绑定数据信息
type TMyResultObject = class(TObject) private FIntegerValue: Integer; FStringValue: String; public property IntegerValue: Integer read FIntegerValue write FIntegerValue; property StringValue: String read FStringValue write FStringValue; end;
由于一致性的原因,这个对象与上述两个对象很像。
现在进行到数据绑定部分,你需要创建一个绑定表达式告诉LiveBinding引擎如何去绑定对象,如何去操作被绑定的数据。
下面的代码片段向你展示了如何去绑定输入(MyObject1和MyObject2)的两个属性到输出对象(MyResultObject)。语法可能有点复杂,下文中我会详细说明。
var BindingExpression1: TBindingExpression; BindingExpression2: TBindingExpression; begin { a binding expression that binds the two Integer properties of the given objects } BindingExpression1 := TBindings.CreateManagedBinding( { inputs } [TBindings.CreateAssociationScope([ Associate(MyObject1, 'o1'), Associate(MyObject2, 'o2') ])], 'o1.IntegerValue + o2.IntegerValue', { outputs } [TBindings.CreateAssociationScope([ Associate(MyResultObject, 'res') ])], 'res.IntegerValue', nil); { a binding expression that binds the two String properties of the given objects } BindingExpression2 := TBindings.CreateManagedBinding( { inputs } [TBindings.CreateAssociationScope([ Associate(MyObject1, 'o1'), Associate(MyObject2, 'o2') ])], 'o1.StringValue + o2.StringValue', { outputs } [TBindings.CreateAssociationScope([ Associate(MyResultObject, 'res') ])], 'res.StringValue', nil); end;
上面代码片段的语法用System.Bindings.Helper.TBindings.CreateManagedBinding创建了一个托管绑定表达式。关于System.Bindings.Helper.TBindings.CreateManagedBinding请查看帮助
The array of input scopes (RealObject, ScriptObject) is given as:
输入范围数组 (真实对象, 脚本对象)如下:
[TBindings.CreateAssociationScope([ Associate(MyObject1, 'o1'), Associate(MyObject2, 'o2') ])]
关于这个输入范围,我想在这里说说,这个scope我一时找不到合适的词来解释,那什么是scope?在程序里,程序是从上往下执行的,如果我在前面部分声明了一个变量,在函数里声明的,那这个变量是局部变量,那么这个scope就是在这个函数里面,如果我是全局变量,那么这个scope是在变量定义后的整个代码段。而这里所说的是变量,这些变量可以在绑定表达式里使用的脚本对象。就像上面代码所写的那样,脚本里的O1就与MyObject1对应起来了,在脚本里访问O1就相当于访问MyObject1一样!这就是scope. 在下文中,scope就不翻译了,直接用scope
输入scope中的绑定表达式其实是一个简单的在两个输入对象整形属性之间的加法运算。
'o1.IntegerValue + o2.IntegerValue'
同理,输出scopes和输出绑定表达式与输入可以理解,输出绑定的表达式将会影响MyResultObject.
为了绑定表达式被运行与编译,你需要运行Notify 命令去触发绑定表达式, 当一个对象的属性值发生改变时,你都需要调用Notify命令去触发绑定表达式,如下面的代码片段所示:
{ if the IntegerValue or StringValue for MyObject1 changes, use the following lines of code } TBindings.Notify(MyObject1, 'IntegerValue'); TBindings.Notify(MyObject1, 'StringValue'); { if the IntegerValue or StringValue for MyObject2 changes, use the following lines of code } TBindings.Notify(MyObject2, 'IntegerValue'); TBindings.Notify(MyObject2, 'StringValue'); { or any other combination of the two above, depending on which value changes }
program LiveBindingProgr; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Bindings.Expression, System.Bindings.ObjEval, System.Bindings.Helper; type TMyObject1 = class(TObject) private FIntegerValue: Integer; FStringValue: String; public property IntegerValue: Integer read FIntegerValue write FIntegerValue; property StringValue: String read FStringValue write FStringValue; end; TMyObject2 = class(TObject) private FIntegerValue: Integer; FStringValue: String; public property IntegerValue: Integer read FIntegerValue write FIntegerValue; property StringValue: String read FStringValue write FStringValue; end; TMyResultObject = class(TObject) private FIntegerValue: Integer; FStringValue: String; public property IntegerValue: Integer read FIntegerValue write FIntegerValue; property StringValue: String read FStringValue write FStringValue; end; var MyObject1: TMyObject1; MyObject2: TMyObject2; MyResultObject: TMyResultObject; BindingExpression1: TBindingExpression; BindingExpression2: TBindingExpression; begin MyObject1 := TMyObject1.Create; MyObject2 := TMyObject2.Create; MyResultObject := TMyResultObject.Create; MyObject1.IntegerValue := 1; MyObject1.StringValue := 'LiveBinding '; MyObject2.IntegerValue := 2; MyObject2.StringValue := 'power.'; { a binding expression that binds the two Integer properties of the given objects } BindingExpression1 := TBindings.CreateManagedBinding( { inputs } [TBindings.CreateAssociationScope([ Associate(MyObject1, 'o1'), Associate(MyObject2, 'o2') ])], 'o1.IntegerValue + o2.IntegerValue', { outputs } [TBindings.CreateAssociationScope([ Associate(MyResultObject, 'res') ])], 'res.IntegerValue', nil); { a binding expression that binds the two String properties of the given objects } BindingExpression2 := TBindings.CreateManagedBinding( { inputs } [TBindings.CreateAssociationScope([ Associate(MyObject1, 'o1'), Associate(MyObject2, 'o2') ])], 'o1.StringValue + o2.StringValue', { outputs } [TBindings.CreateAssociationScope([ Associate(MyResultObject, 'res') ])], 'res.StringValue', nil); TBindings.Notify(MyObject1, 'IntegerValue'); TBindings.Notify(MyObject1, 'StringValue'); Writeln('Result of add operation: ', MyResultObject.IntegerValue); Writeln(MyResultObject.StringValue); Readln; MyObject1.Free; MyObject2.Free; MyResultObject.Free; end.
运行程序,控制面板输出结果如下:
Result of add operation: 3 LiveBinding power.