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

    开始之前,可以复习一下kbmMWSmartBind实现ListView绑定数据集进阶篇(三)

    在这篇文章中,我分享了如何将ClientQuery与Listview绑定,以及遇到的问题的解决方法,但并不完美,还存在问题。

    那最好的实现方案应该是这样的:

    1. 绑定代码只执行一次
    2. 支持ClientQuery重复打开
    3. 有最好的效率
    4. 支持跨平台,比如android
    5. 不用在设计期设计好字段列表
    6. 界面与逻辑分离

    现在,基于kbmMW 5.12来看看如何实现?

    第一步,声明绑定对象并建立实例以及对象的销毁

      private
        FNavigatorZC:IkbmMWBinding;
        FBindOrderZC:TkbmMWBindings;
    
    procedure TMyFrame.AfterConstruction;
    begin
      inherited;
      FBindOrderZC:=TkbmMWBindings.Create;
    
    end;
    
    procedure TMyFrame.BeforeDestruction;
    begin
      inherited;
      FNavigatorZC:=nil;
      FBindOrderZC.Shutdown;
      FBindOrderZC.DisposeOf;
    end;
    

    因为我用的Frame类,所以必须在 AfterConstruction建立以及在BeforeDestruction中销毁。

    第二步,建立一个绑定方法,实现具体的绑定。

    procedure TMyFrame.Binding;
    begin
      if FNavigatorZC=nil then
      begin
           FNavigatorZC:=FBindOrderZC.Bind(TCpzsInfo(DataInfo).qOrderZC, 'fsn', ListView1, '#fsn');//必须在这一行取得FNavigatorZC
           FBindOrderZC.Bind(qOrderZC, 'FDate',         ListView1, '#fdate');
           FBindOrderZC.Bind(qOrderZC, 'FTruckName',    ListView1, '#ftruckname');
           FBindOrderZC.Bind(qOrderZC, 'FcustomerName', ListView1, '#fcustomername');
           FBindOrderZC.Bind(qOrderZC, 'FUserName',     ListView1, '#fusername');
           FBindOrderZC.Bind(qOrderZC, 'FState',        ListView1, '#fstate');
           FBindOrderZC.Bind(qOrderZC, 'FID',           ListView1, '#fid');
           FBindOrderZC.Bind(qOrderZC, '@',             ListView1, '@', [mwboTwoWay]);
      end;
      FNavigatorZC.Navigator.Refresh;
      FNavigatorZC.Navigator.Refresh;//这要执行两次,不然可能会显示不正确
    
    end;
    

    通过代码,可以看到,利用FNavigatorZC来避免重复绑定。

    第三步,打开数据集,并执行Binding方法,进行绑定

    procedure TMyFrame.QueryOrderZC;
    begin
      qOrderZC.DisableControls;
      try
          qOrderZC.AutoFieldDefsOnOpen:=mwafoOnce;//只取一次字段定义
          qOrderZC.Close;
          qOrderZC.Query.Text:='select * from OrderZC where FState=0';
          qOrderZC.Open;
          qOrderZC.Fields.LifeCycles:= [lcPersistent];//持久化字段定义,避免重建字段
      finally
          qOrderZC.EnableControls;
      end;
    end;

    第四步,执行绑定

    ...
    QueryOrderZC;
    Binding;
    ...
    

    上面的两行代码是可以重复执行的,所以说,支持ClientQuery的重复打开。

    好了,本文章中所有代码都是实际项目提练出来,并经过生产验证,你可以放心按这个方式去使用。

    2020-06-04:补充内容:

    遇到按上面思路实现后,在一个功能中,有一个Listview显示不正常,第一次打开数据集显示正常,第二次数据集的sql变了,内容也变了,这时候Listview在android下不能同步显示,但是在win32下是正常的,百思不得期解。最后发现原因,原来在bind方法中为FNavigatorZC赋值的位置不对,FNavigatorZC在绑定同步位置时取得的,改到第一行,在绑定具体字段与Text对象时取得。

    错误的写法是这样的:

    procedure TMyFrame.Binding;
    begin
      if FNavigatorZC=nil then
      begin
           FBindOrderZC.Bind(TCpzsInfo(DataInfo).qOrderZC, 'fsn', ListView1, '#fsn');
           FBindOrderZC.Bind(qOrderZC, 'FDate',         ListView1, '#fdate');
           FBindOrderZC.Bind(qOrderZC, 'FTruckName',    ListView1, '#ftruckname');
           FBindOrderZC.Bind(qOrderZC, 'FcustomerName', ListView1, '#fcustomername');
           FBindOrderZC.Bind(qOrderZC, 'FUserName',     ListView1, '#fusername');
           FBindOrderZC.Bind(qOrderZC, 'FState',        ListView1, '#fstate');
           FBindOrderZC.Bind(qOrderZC, 'FID',           ListView1, '#fid');
           FNavigatorZC:=FBindOrderZC.Bind(qOrderZC, '@',ListView1, '@', [mwboTwoWay]);//这是错误的写法,造成Listview在android下不能同步显示,win下正常。
      end;
      FNavigatorZC.Navigator.Refresh;
      FNavigatorZC.Navigator.Refresh;//这要执行两次,不然可能会显示不正确
    
    end;
    

    2020-06-12 在生产现场应用这些天,app工作正常!用户反应,界面显示效率比以前快多了! 实践证明上面调用方法可行。

  • 相关阅读:
    关于 广义相对论 引力红移 的 一个 疑问
    随便 说说 非欧几何
    收录 几篇 关于 电磁波 麦克斯韦方程 的 文章
    从 广义相对论 看到 “数学陷阱”
    对 广义相对论 的 评价
    收录 几篇 关于 广义相对论 水星进动 的 文章
    关于 1 和 0.999999……
    我对 量子力学 提出了一个 修正,名为 “K氏修正”
    随便记录点 在 贴吧 里 讨论 广义相对论 的 想法
    C#程序员初学Python
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/13036316.html
Copyright © 2011-2022 走看看