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]。

原文地址:https://www.cnblogs.com/kinglandsoft/p/13024749.html