Martyn,
This did not address my question. I did not want to place the datamodule unit in my uses section at all. Instead i wanted to "inject" the dataset by setting datasource.dataset.
I was able to find a solution. It involves causing the linkControltoField1 property to "refresh" by setting its active property to false and then to true after the dataset property is set. Here is my code. (D10.1 Berlin)
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.
Here is the dfm file in text.
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
The datamodule is unremarkable. Simply a FDTable and FDconnection. I attached them to the dbDemos database. Note Unit1 does not use 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.
Last, here is the program unit. Here is where I set the dataset property.
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.