2016-09-23 20 views
0

當運行時設置Datast的Dataset屬性時,如何讓除非TStringGrid的控件能夠與Livebindings一起正常工作?我能夠得到一個TStringGrid來識別數據集字段,但不是其他控件,如TEdit。當在運行時設置datasource.dataset時,無法獲取TEdit與Livebindings下的數據集連接

這裏是我的項目的細節。我創建了一個datamodule和一個表單。具有數據集對象和表單的datamodule具有數據源以及UI控件。爲了減少模塊之間的依賴關係,我不希望表單元使用數據模塊單元。相反,我想在運行時設置datasource.dataset。如果我使用TStringGrid,這個策略是有效的,但是對於TEdit,它不會。我曾嘗試在LiveBindings中手動創建字段,但這些字段不映射到數據集。如果我使用VCL,這將是一個非問題,但我一直無法找出用Livebindings完成此任務的最佳方法。 FYI,這是一個FMX項目。

我還注意到,如果我「使用」datamodule創建Livebinding連接,並隨後未使用它,字段顯示在BindSourceDb和讀取(無效)。當我運行應用程序並在運行時設置數據集屬性時,TEdit控件能夠找到可以正常工作的字段。任何建議如何做到這一點,而不使用和使用模塊?

+0

「使用」我的意思是我將文件添加到其中一個使用部分,「unuse」意味着我將其刪除。 – joeb545

+0

「使用」我的意思是我將文件添加到實施中的使用部分,「不使用」意味着我將其刪除。我正在編程接口。表單有一個名爲ViewModel的接口屬性,我在創建表單後立即設置它。在ViewModel集合過程中,有代碼讀取Datasource.Dataset:= ViewModel.Dataset。數據源已經連接到BindSourceDb。如果我使用數據感知應用程序進行此操作,則附加到數據源的所有控件都會自動連接並填充數據。我如何使用Livebindings進行這項工作? – joeb545

回答

0

以下項目對我使用LiveBindings工作正常。我做了我 明白你要說明,即

  • 的表格單元,DynLiveBindingsu,initally使用的數據模塊單元DynDMu。在這種情況下, 我將活動綁定組件添加到表單並「將它們連接起來」,從 開始填充BindingList對象,然後使用它添加TLinkGridToDataSource和TLinkControlToField並設置它們的屬性。

  • 然後,我刪除了從表格的用途清單,編制 引用DynDMu跑項目和StringList1和EDIT1正確綁定到數據模塊的 數據集。

很明顯,我不能看到你的項目,所以不知道爲什麼你得到一個問題, 但至少這個答案讓你與你的一個 比較的基礎上,使用一個工作項目。

請注意,順便說一下,在數據模塊或表單中沒有涉及TDataSource。

我使用德爾福西雅圖,順便說一句。

DataModule的:

unit DynDMu; 
[...] 
type 
    TDataModule1 = class(TDataModule) 
    CDS1: TClientDataSet; 
    CDS1Name: TStringField; 
    CDS1ID: TIntegerField; 
    procedure DataModuleCreate(Sender: TObject); 
    end; 

[...] 

procedure TDataModule1.DataModuleCreate(Sender: TObject); 
begin 
    CDS1.CreateDataSet; 
    CDS1.InsertRecord([1, 'One']); 
    CDS1.InsertRecord([2, 'Two']); 
    CDS1.InsertRecord([3, 'Three']); 
end; 

表格單元

unit DynLiveBindingsu; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.Bind.EngExt, 
    Vcl.Bind.DBEngExt, Vcl.Bind.Grid, System.Rtti, System.Bindings.Outputs, 
    Vcl.Bind.Editors, Data.Bind.Components, Data.Bind.DBScope, Data.Bind.Grid, 
    Data.DB, Vcl.StdCtrls, Vcl.Grids, Data.Bind.Controls, Vcl.ExtCtrls, 
    Vcl.Buttons, Vcl.Bind.Navigator; 

type 
    TForm1 = class(TForm) 
    StringGrid1: TStringGrid; 
    Edit1: TEdit; 
    BindingsList1: TBindingsList; 
    LinkGridToDataSource1: TLinkGridToDataSource; 
    BindSourceDB1: TBindSourceDB; 
    BindNavigator1: TBindNavigator; 
    LinkControlToField1: TLinkControlToField; 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

end. 

形式DFM

object Form1: TForm1 
[...] 
    object StringGrid1: TStringGrid 
    [...] 
    end 
    object Edit1: TEdit 
    [...] 
    end 
    object BindNavigator1: TBindNavigator 
    Left = 16 
    Top = 150 
    Width = 240 
    Height = 25 
    DataSource = BindSourceDB1 
    Orientation = orHorizontal 
    TabOrder = 2 
    end 
    object BindingsList1: TBindingsList 
    Methods = <> 
    OutputConverters = <> 
    Left = 216 
    Top = 184 
    object LinkGridToDataSource1: TLinkGridToDataSource 
     Category = 'Quick Bindings' 
     DataSource = BindSourceDB1 
     GridControl = StringGrid1 
     Columns = < 
     item 
      MemberName = 'ID' 
     end 
     item 
      MemberName = 'Name' 
     end> 
    end 
    object LinkControlToField1: TLinkControlToField 
     Category = 'Quick Bindings' 
     DataSource = BindSourceDB1 
     FieldName = 'Name' 
     Control = Edit1 
     Track = False 
    end 
    end 
    object BindSourceDB1: TBindSourceDB 
    DataSet = DataModule1.CDS1 
    ScopeMappings = <> 
    Left = 296 
    Top = 184 
    end 
end 
+0

@ joeb545:您是否設法確定您的項目無法正常工作而我的工作? – MartynA

0

馬丁,

這並沒有解決我的問題。我不想將datamodule單元放置在我的使用部分中。相反,我想通過設置datasource.dataset來「注入」數據集。

我能找到解決方案。它涉及通過將其active屬性設置爲false來「刷新」linkControltoField1屬性,然後在設置dataset屬性後將其設置爲true。這是我的代碼。 (D10.1柏林)

unit Unit1; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Rtti, System.Bindings.Outputs, 
    Vcl.Bind.Editors, Data.Bind.EngExt, Vcl.Bind.DBEngExt, FireDAC.Stan.Intf, 
    FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, 
    FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt, 
    FireDAC.UI.Intf, FireDAC.VCLUI.Wait, FireDAC.Stan.Def, FireDAC.Stan.Pool, 
    FireDAC.Phys, FireDAC.Phys.MSAcc, FireDAC.Phys.MSAccDef, Data.Bind.Controls, 
    Vcl.ExtCtrls, Vcl.Buttons, Vcl.Bind.Navigator, Data.DB, FireDAC.Comp.Client, 
    FireDAC.Comp.UI, FireDAC.Comp.DataSet, Data.Bind.Components, Vcl.StdCtrls, 
    Data.Bind.DBScope, Data.Bind.ObjectScope, Vcl.Bind.Grid, Data.Bind.Grid, 
    Vcl.Grids; 

type 
    TForm1 = class(TForm) 
    BindSourceDB1: TBindSourceDB; 
    Edit1: TEdit; 
    BindingsList1: TBindingsList; 
    DataSource1: TDataSource; 
    FDGUIxWaitCursor1: TFDGUIxWaitCursor; 
    NavigatorBindSourceDB1: TBindNavigator; 
    StringGrid1: TStringGrid; 
    LinkGridToDataSourceBindSourceDB1: TLinkGridToDataSource; 
    Button1: TButton; 
    Button2: TButton; 
    Button3: TButton; 
    LinkControlToField1: TLinkControlToField; 
    procedure Button1Click(Sender: TObject); 
    private 
    function GetDataset: Tdataset; 
    procedure SetDataset(const Value: Tdataset); 
    { Private declarations } 
    public 
    { Public declarations } 
    property Dataset: Tdataset read GetDataset write SetDataset; 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    BindSourceDb1.DataSource := DataSource1; 
    LinkControlToField1.DataSource := BindSourceDB1; 
    LinkControlToField1.Active := False; //in order for this to work you must 
    LinkControlToField1.Active := True; // set link to false then to true 

end; 

function TForm1.GetDataset: Tdataset; 
begin 
    Result := Datasource1.DataSet; 
end; 

procedure TForm1.SetDataset(const Value: Tdataset); 
begin 
    Datasource1.DataSet := Value; 
    BindSourceDb1.DataSource := DataSource1; 
    LinkControlToField1.DataSource := BindSourceDB1; 
    LinkControlToField1.Active := False; //in order for this to work you must 
    LinkControlToField1.Active := True; // set link to false then to true 
end; 

end. 

這是文本中的dfm文件。

object Form1: TForm1 
    Left = 0 
    Top = 0 
    Caption = 'Form1' 
    ClientHeight = 299 
    ClientWidth = 635 
    Color = clBtnFace 
    Font.Charset = DEFAULT_CHARSET 
    Font.Color = clWindowText 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    PixelsPerInch = 96 
    TextHeight = 13 
    object Edit1: TEdit 
    Left = 184 
    Top = 88 
    Width = 121 
    Height = 21 
    TabOrder = 0 
    end 
    object NavigatorBindSourceDB1: TBindNavigator 
    Left = 280 
    Top = 24 
    Width = 240 
    Height = 25 
    DataSource = BindSourceDB1 
    Orientation = orHorizontal 
    TabOrder = 1 
    end 
    object StringGrid1: TStringGrid 
    Left = 168 
    Top = 112 
    Width = 320 
    Height = 120 
    ColCount = 1 
    FixedCols = 0 
    RowCount = 2 
    TabOrder = 2 
    ColWidths = (
     64) 
    RowHeights = (
     24 
     24) 
    end 
    object Button1: TButton 
    Left = 208 
    Top = 256 
    Width = 75 
    Height = 25 
    Caption = 'Button1' 
    TabOrder = 3 
    OnClick = Button1Click 
    end 
    object Button2: TButton 
    Left = 352 
    Top = 256 
    Width = 75 
    Height = 25 
    Caption = 'Button2' 
    TabOrder = 4 
    end 
    object Button3: TButton 
    Left = 464 
    Top = 256 
    Width = 75 
    Height = 25 
    Caption = 'Button3' 
    TabOrder = 5 
    end 
    object BindSourceDB1: TBindSourceDB 
    ScopeMappings = <> 
    Left = 432 
    Top = 128 
    end 
    object BindingsList1: TBindingsList 
    Methods = <> 
    OutputConverters = <> 
    Left = 20 
    Top = 5 
    object LinkGridToDataSourceBindSourceDB1: TLinkGridToDataSource 
     Category = 'Quick Bindings' 
     DataSource = BindSourceDB1 
     GridControl = StringGrid1 
     Columns = <> 
    end 
    object LinkControlToField1: TLinkControlToField 
     Category = 'Quick Bindings' 
     FieldName = 'LastName' 
     Control = Edit1 
     Track = True 
    end 
    end 
    object DataSource1: TDataSource 
    Left = 496 
    Top = 184 
    end 
    object FDGUIxWaitCursor1: TFDGUIxWaitCursor 
    Provider = 'Forms' 
    Left = 384 
    Top = 64 
    end 
end 

datamodule不起眼。簡單的FDTable和FDconnection。我將它們附加到dbDemos數據庫。注意Unit1不使用Unit2。

unit Unit2; 

interface 

uses 
    System.SysUtils, System.Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option, 
    FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, 
    FireDAC.DApt.Intf, FireDAC.Stan.Async, FireDAC.DApt, FireDAC.UI.Intf, 
    FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Phys, FireDAC.Phys.MSAcc, 
    FireDAC.Phys.MSAccDef, FireDAC.VCLUI.Wait, Data.DB, FireDAC.Comp.Client, 
    FireDAC.Comp.DataSet; 

type 
    TDataModule2 = class(TDataModule) 
    FDTable1: TFDTable; 
    FDConnection1: TFDConnection; 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    DataModule2: TDataModule2; 

implementation 

{%CLASSGROUP 'Vcl.Controls.TControl'} 

{$R *.dfm} 

end. 

最後,這裏是程序單元。這是我設置數據集屬性的地方。

program Project1; 

uses 
    Vcl.Forms, 
    Unit1 in 'Unit1.pas' {Form1}, 
    Unit2 in 'Unit2.pas' {DataModule2: TDataModule}; 

{$R *.res} 

begin 
    Application.Initialize; 
    Application.MainFormOnTaskbar := True; 
    Application.CreateForm(TDataModule2, DataModule2); 
    Application.CreateForm(TForm1, Form1); 

    Form1.Dataset := Datamodule2.FDTable1; //Injecting the dataset property 

    Application.Run; 
end. 
相關問題