在运行时设置datasource.dataset时,无法让TEdit连接到Livebindings下的数据集

时间:2016-09-23 20:33:20

标签: delphi livebindings

如果在运行时设置数据源的数据集属性时,如何使用TStringGrid以外的控件与Livebindings一起正常工作?我可以让TStringGrid识别数据集字段,但不能识别其他控件,如TEdit。

以下是我的项目的详细信息。我创建了一个数据模块和一个表单。具有数据集对象和表单的数据模块具有数据源和UI控件。为了减少模块之间的依赖关系,我不希望表单单元使用数据模块单元。相反,我想在运行时设置datasource.dataset。如果我使用TStringGrid,这个策略可行,但是对于TEdit,它没有。我尝试在LiveBindings中手动创建字段,但这些字段不会映射到数据集。如果我使用VCL,这将是一个非问题,但我一直无法找到使用Livebindings实现这一目标的最佳方法。仅供参考,这是一个FMX项目。

我还注意到,如果我“使用”数据模块来创建Livebinding连接并随后将其使用,则字段显示在BindSourceDb上并读取(无效)。当我运行应用程序并在运行时设置dataset属性时,TEdit控件能够找到一个可以正常工作的字段。如何在不使用和使用模块的情况下做任何建议?

2 个答案:

答案 0 :(得分:0)

使用LiveBindings,以下项目对我来说很好。我做了我 理解你要描述,即

  • Form单元DynLiveBindingsu最初使用数据模块单元DynDMu。在那种情况下, 我将实时绑定组件添加到表单并“连接起来”,从开始 填充BindingList对象,然后使用它添加TLinkGridToDataSource和TLinkControlToField并设置它们的属性。

  • 然后,我从表单的Uses列表中删除了对DynDMu的引用,编译 并运行该项目并将StringList1和Edit1正确绑定到 数据模块中的数据集。

显然我看不到你的项目,所以不知道你为什么会遇到问题, 但至少这个答案给你一个工作项目作为一个基础 与你的比较。

请注意,顺便说一句,在数据模块或表格中没有涉及TDataSource。

我正在使用Delphi Seattle,顺便说一句。

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

答案 1 :(得分:0)

马丁,

这没有解决我的问题。我根本不想将数据模块单元放在我的使用部分。相反,我想通过设置datasource.dataset来“注入”数据集。

我能够找到解决方案。它涉及使linkControltoField1属性通过将其active属性设置为false来“刷新”,然后在设置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

数据模块不起眼。简单的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.