kbmMW 5.12试用笔记
1.为了使用CrossSocket的Transport,还要手工在kbmMWConfig.inc中增加:
{$DEFINE KBMMW_NATIVETRANSPORT_SUPPORT}
2.SmartBind支持ClientQuery重新打开不用重新绑定的问题
对于这一问题,没有完全解决。看一下AutoFieldDefsOnOpen在不同值的情况下的测试结果:
(1)对于ClientQuery在设计期建好字段,设置AutoFieldDefsOnOpen=mwafoNever,测试正常。
(2)对于ClientQuery在设计期不建字段,设置AutoFieldDefsOnOpen=mwafoOnce,Win测试正常,Android不正常。
(3)对于ClientQuery在设计期不建字段,设置AutoFieldDefsOnOpen=mwafoAlways,Win测试不正常,出地址错误。Android不正常。出Field 'FName' has no dataset.
(2)与(3)在Android下,错误是一样的,第一次打开ClientQuery正常,第二次就会产生Field 'FName' has no dataset.
下面是具体的测试代码:
private FBindOrderZC:TkbmMWBindings; FNavigatorZC:IkbmMWBinding; procedure TForm2.bind; begin if FNavigatorZC=nil then begin FNavigatorZC:=FBindOrderZC.Bind(q, 'FID', ListView1, '#Text1'); FBindOrderZC.Bind(q, 'FName', ListView1, '#Text2'); FBindOrderZC.Bind(q, 'FInt', ListView1, '#Text3'); FBindOrderZC.Bind(q, 'FInt64', ListView1, '#Text4'); FBindOrderZC.Bind(q, '@', ListView1, '@', [mwboTwoWay]); end; FNavigatorZC.Navigator.Refresh; FNavigatorZC.Navigator.Refresh; end; procedure TForm2.Button1Click(Sender: TObject); begin q.AutoFieldDefsOnOpen:= mwafoOnce; q.Close; q.Open; bind; end;
a.当重新打开数据集时,可能会出现
出此错的原因,我想就是smartbind在同步数据时,数据集处在关闭状态而产生。尽管我用了DataSet.DisableControls,也是不行。对此,在重新打开数据集时,先关闭自动同步,调用 FBindOrderZC.UpdateEvent.Activate(False);打开后再执行 FBindOrderZC.UpdateEvent.Activate(True);开始执行自动同步。这种代码的写法,还是紧偶合界面与DataModule,不爽!
b.当设置AutoFieldDefsOnOpen=mwafoNever,在windows下正常,但在android下重新打开数据集时会出现:
这个问题,在上个版本就发现,并发到作者的Forums,没有解决掉。当时没给作者写demo,估计他不清楚具体的问题。
c.FNavigatorZC.Navigator.Refresh;还是要调用两次,不然可能会出现显示结果不正常。
d.DataSet is not in edit mode错误。
下面这个方法还要修正,通过Navigator.Value['fid]:=1这种写法,会产生DataSet is not in edit mode。
procedure TkbmMWBindingDatasetNavigator.SetValue(const AName:string; const AValue:TValue); var fld:TField; begin if IsValid then begin fld:=FDataset.FindField(AName); if fld<>nil then begin if not (FDataset.State in [dsInsert,dsEdit]) then//+++ FDataSet.Edit;//+++ fld.AsVariant:=TkbmMWRTTI.ConvertValue2Variant(AValue,nil); end; end; end;
针对上面的例子,给者写了demo并发给作者,期待回复。
对于“Field 'FName' has no dataset”这个问题,找到一个解决办法,见下面的代码:
procedure TForm2.Button1Click(Sender: TObject);
begin
kbmMWClientConnectionPool1.Active:=False;
kbmMWTCPIPIndyClientTransport1.Host:=Edit1.Text;
kbmMWTCPIPIndyClientTransport1.Port:=Edit2.Text.ToInteger;
q.AutoFieldDefsOnOpen:= mwafoOnce;
q.Fields.LifeCycles:= [lcPersistent];//解决在android上第二次打开时出现Field 'FName' has no dataset
q.Query.Text:='select * from t1';
q.Open;
bind;
end;
为什么这一句就解决了问题呢?
如果我们在设计期定义了字段,那LifeCycles值就为lcPersistent,表示是持久化的字段,在TDataset.Open时,不再重新建立Field对象。
现在我们加了这行代码,相当于在设计期建了字段!
注意:这行代码必须的TDataset打开的情况下执行!具体可以看一下Fields.LifeCycles这个属性值的SetLiftCycles方法,从中可以看到,这个方法是将Fields中每个字段设置为lcPersistent。而Close数据集时,会根据每个字段的LifeCycles属性来决定是否删除Field对象,如果是lcPersistent,则不删除。因此,我们要确保在Close前或Open后来执行Fields.LifeCycles:= [lcPersistent]。