• kbmMW 5.10.10 SmartBinding问题修正


    2020-01-09:kbmMW 5.10.20解决了下面的问题,如果你已经升级到该版本,则下面内容没必要读了!

    千呼万唤始出来,最新的kbmMW 5.10.01终于发布了,详情可以看xalion发的更新日志

    我期待的Smartbinding for Listview终于来了,在这一版本中,对SmartBinding做了大量的功能扩展与更新,对Listview只是其中之一。这几天一直测试这个Listview的支持情况,发现一个致命的问题,看下面这行代码:

    bnd:=Binding.Bind(dataset,'f1',Edit1,'Text',[mwboTwoWay]);

    将dataset的f1字段绑定到Edit1的Text属性上,采用双向绑定的方式,目的是通过Edit1,能编辑字段,如同VCL下的DBEdit的一样工作。

    但实际的运行情况,与预期不符,当绑定后,SmartBinding将Edit1.Text写到dataset的f1字段中,正好写反了!见下图:

    初始情况下,控件Edit1的属性Text值为“Edit1",f1字段值为0,现在”Edit1"正好写入dataset的f1字段中,然后ListView也显示了字段的值为"Edit1"。

    向作者反应了这个问题,但作者并没有确认这是一个bug,只好自己动手,通过读SmartBinding的代码,找到一个解决方法,按下面代码修改,所有TkbmMWBinding.Create重载的版本都要改。

    constructor TkbmMWBinding.Create(const ABindings:TkbmMWBindings;
                                     const ASource:TValue; const ASourceMember:string;
                                     const ADestination:TValue; const ADestinationMember:string;
                                     const AOptions:TkbmMWBindingOptions = []);
    var
       v:TValue;
       b:boolean;
    begin
         inherited Create;
         ....
         UpdateInfo;
    
         FDestinationProxy.SetValue(FSourceProxy.Value,true); //增加这一行.
    
    end;

    改后,我们再看看实际运行情况:

    上面两个Edit控件及下面的ListView控件终于都显示数据集的内容了!

    原理分析:

    SmartBinding绑定,就是用TkbmMWBindings来管理TkbmMWBinding对象,即调用TkbmMWBindings.bind增加一个绑定时,会建立一个TkbmMWBinding对象,并将这个对象加到TkbmMWBindings内部的列表中。问题就出在建立TkbmMWBinding对象过程中,没有将数据源的值赋值给目标源,然后,当SmartBind做数据同步时,错误的将目标源的值回写给了数据源,造成逻辑上的错误。我这里的修改,就是增加了这一步:将数据源的值赋值给目标源。

    2019-11-26

    kbmMW 5.10.10没有按我的意思改,作者认为这不是问题?

    2019-11-27

    Aone提出这样改,可以避免问题。

    procedure TForm1.Button9Click(Sender: TObject);
    begin
    
      bnd:=nil;
      Binding.Clear;
      //ListView1.Items.Clear;
    
      dataset:=mt;
    
      dataset.DisableControls;
    
      bnd:=Binding.Bind(dataset,'f1',Edit1,'Text',[mwboTwoWay]);
           Binding.Bind(dataset,'f2',Edit2,'Text',[mwboTwoWay]);
           Binding.Bind(dataset,'f3',DateEdit1,'Date',[mwboTwoWay]);
    
      bnd:= Binding.Bind(dataset,'f1',ListView1,'#Text1');
      Binding.Bind(dataset,'f2',ListView1,'#Text2');
      Binding.Bind(dataset,'f3',ListView1,'#Text3');
    
      Binding.Bind(dataset,'@',ListView1,'@',[mwboTwoWay]);
    
      dataset.EnableControls;
    
    end;

    kbmMW 5.10.10新问题:(5.10.20还存在这个问题)

    procedure TForm1.Button11Click(Sender: TObject);
    begin
    
        bnd.Navigator.Append;
        bnd.Navigator.Value['f1']:='101';
        bnd.Navigator.Value['f2']:=101;
    
    end;

    上面代码产生错误:dataset 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;

    发给作者,等修正!

  • 相关阅读:
    a标签上window.location.href无法跳转
    Directive指令的scope配置项使用说明
    Echarts 里面获取纵坐标刻度的间距
    使用 Supervsior 守护进程
    linux 下的快捷键操作
    前端必须掌握的 nginx 技能(4)
    在 vue 中用 transition 实现轮播效果
    前端必须掌握的 nginx 技能(3)
    前端必须掌握的 nginx 技能(2)
    前端必须掌握的 nginx 技能(1)
  • 原文地址:https://www.cnblogs.com/kinglandsoft/p/11865996.html
Copyright © 2020-2023  润新知