zoukankan      html  css  js  c++  java
  • kbmMWSmartBind实现ListView绑定数据集进阶篇(二)

    前文写过进阶篇一,实现了绑定后,如何重画Listview的Item。接下来,我们看看在实际项目中,如何应付各种坑?

    第一个坑,关于绑定控制时间点,即在什么时候进行绑定。

    在进阶篇一中,我们用的MemTable,是感觉不到这一点的。大家知道,在实际项目中,常常用TClientQuery做查询并得到数据集,这时候你每做一次查询,ClientQuery都会关闭再打开,并且重建TField对象,如果你绑定的时间点不对,会造成各种错误。先看一下我测试通过的代码实现:

        FBindOrder.UpdateEvent.Activate(False);//停止绑定的同步更新
        FBindOrder.Clear;//这里清空绑定的内容
        Scheduler.Run(
          procedure(const AScheduledEvent: IkbmMWScheduledEvent)
          begin
                 ....
                 ClientQuery.Open;//执行查询
          end).SynchronizedAfterRun(
          procedure(const AScheduledEvent: IkbmMWScheduledEvent)
          begin
           FBindOrder.Bind(ClientQuery,'FSN',ListView1,'#fsn').ToDestinationExpression('"业务单号:"+data');
    ......
            FBindOrder.UpdateEvent.Activate;//开始绑定的同步更新
          end).WhenException(
          procedure(const AException: Exception)
          begin
            ApplicationShowException(AException);
          end).Activate;

    经过这样的绑定,重复执行这段代码时,Smartbind工作正常。总结来说,当一个ClientQuery在打开前,一定要清空原有的绑定,打开后,再重新进行绑定。为什么呢?是因为FBindOrder.Bind方法,会把数据集的字段对象与界面对象加入FBindOrder内部的列表中,并按这个列表进行更新,当关闭ClientQuery再重新Open,数据集的字段对象会重建,已经不再是原来的对象,而FBindOrder内部的列表中的对象已经不存在了,所以必须重新进行绑定。进一步补充,当你做绑定时,一定在数据集打开后,才能进行绑定操作。

    第二个坑,小心绑定的异步执行。

    前文有写过,SmartBind的工作原理,是利用一个调度对象,默认情况下每100毫秒同步数据源(数据集)与目标源(界面控件)。因为是定时同步,所以必须理解为异步执行的。我们看一下,异步执行带来的问题,先看一下代码:

    var
    FBindGoods: TkbmMWBindings;
    begin
       ......  
       FBindGoods := TkbmMWBindings.Create;
       FBindGoods.Clear;
       ClientQueryGoods.Open
       FBindGoods.Bind(ClientQueryGoods, 'FName', Edit1, 'Text');
       ......
       Edit1.Text:='宝马X6';
       ShowMessage(ClientQueryGoods.FieldByName('FName').AsString);
       ......

    上面代码,我们将一个字段与Edit1.Text绑定,然后操作Edit1.Text,再调用ShowMessage显示字段的内容,结果是ShowMessage不会显示“宝马X6”。原因就是SmartBind还没有执行更新动作,将Edit1.Text内容写进字段。这种代码场景,一定要记住,避免异步带给我们的影响。

    换句话说,当你改变数据源或目标源时,因为异步的原因,不能同时更新数据源或目标源,因此,当你更新数据源或目标源后立即从对应的数据源或目标源取得数据,是取不到正确的值的。这不仅影响数据源或目标源的值,同样也影响数据源或目标源的位置。比如,将DataSet与ListView做双向绑定,当你在ListView中选择一行,然后立即从DataSet当前记录中取值,取到的结果将是错误的。

    第三个坑,绑定对象的释放。

    SmartBind为我们提供了全局对象Binding,在实际项目中,是不实用的,还需要我们自己来建立与释放kbmMWBindings。以第二个坑中用到的FBindGoods为例,一定要记得自己释放他,如果在Frame中建立的绑定对象,一定要在BeforeDestruction中释放。

    procedure TMyFrame.BeforeDestruction;
    begin
      bnd:=nil;
      FBindGoods.Shutdown;
      FBindGoods.DisposeOf;
    
      inherited;
    end;

    按上面的代码释放,应用无论在何时退出,都会天下太平,否则将产生各种地址错误。

  • 相关阅读:
    实验七、信号
    实验六 进程基础
    实验五 shell脚本编程
    实验四 Linux系统C语言开发环境学习
    实验三 Linux系统用户管理及VIM配置
    实验二 Linux系统常用操作命令
    实验一Linux系统与应用课程准备
    实验八 进程间通信
    实验七 信号
    实验六 进程基础
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/12680417.html
Copyright © 2011-2022 走看看