红鱼儿

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;

发给作者,等修正!

 

posted on 2019-11-15 14:03  红鱼儿  阅读(431)  评论(0编辑  收藏  举报