SmartBinding實現DataSet與ListView的綁定及同步顯示


kbmMW 5.10.20發布了,這個版本解決了我提出的問題,當對DataSet增刪記錄時,ListView能夠同步顯示。下面看看具體的實現代碼。

為了解決上面的問題,作者為IkbmMWBindingNavigator接口增加了下面的方法:

  IkbmMWBindingNavigator = interface
     ......
     function Delete:boolean;
     function Insert:boolean; overload;
     function Insert(const ANames:array of string; const AValues:array of TValue):boolean; overload;
     function Append:boolean; overload;
     function Append(const ANames:array of string; const AValues:array of TValue):boolean; overload;

     procedure Refresh;

     property Value[const AName:string]:TValue read GetValue write SetValue;
  end;

通過上面的方法,即可實現對數據集的增加、刪除等操作。

接下來看一下具體的實現過程:

第一步,綁定DataSet與ListView並取得返回的接口IkbmMWBinding。通過IkbmMWBinding接口的屬性Navigator,可以訪問IkbmMWBindingNavigator接口,從而調用上面新增的方法。

procedure TForm1.Button9Click(Sender: TObject);
begin

  bnd:=nil;
  Binding.Clear;
  //ListView1.Items.Clear;

  dataset:=mt;
  dataset.disableControls;//kbmMW 5.10.10必須調用,kbmMW 5.10.20可以不調用了,這是改進的地方
  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;//kbmMW 5.10.10必須調用,kbmMW 5.10.20可以不調用了,這是改進的地方
end;

當執行這段代碼后,會出現下面的結果:

 

 ListView正確的顯示了數據集的所有記錄內容。無論我們是執行dataset.Next還是bnd.Navigator.Next,ListView與dataSet都會同步顯示當前記錄的位置。

第二步,實現刪除

現在我們刪除一條記錄:

procedure TForm1.Button12Click(Sender: TObject);
begin
//  mt.Delete;
//  bnd.Navigator.Refresh;

   bnd.Navigator.Delete;

end;

如果直接操作數據集,執行Delete方法,那么,還需要執行bnd.Navigator.Refresh;

如果直接通過bnd執行Delete方法,則不需要執行Refresh方法。

第三步,實現增加

procedure TForm1.Button11Click(Sender: TObject);
begin
//  mt.Append;
//  mt.FieldByName('f1').Value:='101';
//  mt.FieldByName('f2').Value:=101;
//  mt.Post;
//
//  bnd.Navigator.Refresh;

    bnd.Navigator.Append;
    bnd.Navigator.Value['f1']:='101';
    bnd.Navigator.Value['f2']:=101;
    bnd.Navigator.Value['f3']:=Date;

end;

上面代碼,象刪除操作一樣,可以通過數據集實現,也可以通過bnd接口實現。當通過數據集實現時,需要調用Refresh方法。

這里有個bug,kbmMW 5.10.10就存在,現在5.10.20還沒有修復,下面是我修改的代碼:

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 [dsEdit,dsInsert]) then//+++++
                FDataset.Edit;                                            //+++++

             fld.AsVariant:=TkbmMWRTTI.ConvertValue2Variant(AValue,nil);
          end;
     end;
end;

這是個小問題,就是FDataSet沒在編輯狀態。

5.10.10,需要這樣調用:就是退出當前界面時,要清空bnd接口變量,讓Binding能夠正確的釋放,不然,退出應用時會產生AV錯誤。

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
    bnd:=nil;
    Binding.Clear;
end;

kbmMW 5.10.20,SmartBinding綁定TDataSet與TListView,對我來說,是一個質的飛躍!可以實用到項目中了。

當然,在具體使用時,還會遇到一些問題,需要自己來處理,比如,用TDateEdit綁定一個TField,當在TDateEdit中輸入日期,會產生錯誤,

原因就是SmartBinding是即時轉換輸入值到對應的TField,而這時候,還沒有完整的輸入一個日期。可以用下面的代碼來處理:

procedure TForm1.DateEdit1Enter(Sender: TObject);
begin

  Binding.EnableByName('DateEdit1',False);//進入這個控件時,暫時屏蔽綁定

end;

procedure TForm1.DateEdit1Exit(Sender: TObject);
begin
   Binding.EnableByName('DateEdit1',True);//退出時打開綁定
end;

上面只是我暫時想到的辦法,也不太盡人意,但總算避免了出錯。類似的控件還會有這樣的問題,一時間想不出更好的辦法。

查看kbmMW 5.10.20的更新日志,對SmartBinding框架,為TkbmMWScheduler增加了Start, Stop 及 Shutdown 方法,為TkbmMWBindings增加了Shutdown方法,通過Binding.Shutdown調用,TkbmMWEvents也增加了Shutdown方法,退出應用時作者建議我們調用以保證程序更好的退出。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM