问题是TBindSourceDB的MasterSource的正确用法是什么例如
1带有导航器的部门的ListView链接到TBindSourceDB(主数据库)。当按下导航器的“插入”按钮时,另一个列表视图变为活动状态,即城市列表视图。现在,带有另一个导航器的城市ListView链接到另一个TBindSourceDB,即城市(详细信息)。我需要将城市作为部门的主要来源。如何以及在哪里必须这样做?
两者,主要和详细TBindSourceDB都链接到具有MasterSource属性的Firedac TSimpleDataSet组件。我已经在指向主组件的细节上填充了该属性。问题是:当按下“详细”导航按钮插入时,TSimpleDataSet中的OnBeforePost会触发,因为它想执行Post!并且不会触发OnAfterInsert事件。使用Firemonkey和TBindSourceDB组件的工作主机->细节数据的正确模式是哪种?]
如果我理解您的正确要求,我认为下面的项目将向您展示有关添加主记录+明细记录的最重要的事情。我认为TListViews实际上分散了对所需内容的理解,因此我将不使用它们,而是使用一些TEdit来显示Master+详细信息一次记录一行。
根据我的经验,经验法则是避免使用LiveBindings做某事如果有更简单的方法可以做到这一点,那就是建立Master-> Master和Details之间的关系。
因此,表单上的组件列表中是一个TDataSource,它链接了二。它的DataSet属性连接到Master。在细节方面应将Detail的MasterSource属性设置为其,并将其MasterField属性设置为设置为Master的MasterID字段。
添加TDataSource的要点是,它使您能够使用标准TDataset模型及其支持的事件可完成建立所需的所有工作插入新的详细记录与当前MasterRecord之间的链接。这是在Detail的OnNewRecord事件中完成的,其内容如下:
procedure TMasterDetailForm.DetailNewRecord(DataSet: TDataSet);
begin
Detail.FieldByName('DetailID').AsInteger := NextDetailID;
Detail.FieldByName('MasterID').AsInteger := Master.FieldByName('MasterID').AsInteger;
Detail.FieldByName('Name').AsString := Format('DetailID:%d for MasterID:%d ', [NextDetailID, Master.FieldByName('MasterID').AsInteger]);
inc(NextDetailID);
end;
使用TDataSource的好处是,它可以确保正确的Master和Detail插入新的详细信息记录时同步。
唯一的其他重要代码在FormCreate evnt中,该代码用于创建和填充具有一些示例记录的Master和Detail数据集。所有LiveBindings连接在加载表单的DFM时设置。 DFM的摘录在项目源代码下方:
代码
unit MasterDetailListsu;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ListView.Types, Data.Bind.GenData,
Fmx.Bind.GenData, System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.EngExt, Fmx.Bind.DBEngExt,
Data.Bind.Components, Data.Bind.ObjectScope, FMX.Objects, FMX.StdCtrls, FMX.ListView, FMX.ListView.Appearances,
FMX.Layouts, FMX.MultiView,FMX.Memo, Fmx.Bind.Navigator, System.Actions, FMX.ActnList,
FMX.ListView.Adapters.Base, Data.DB, Datasnap.DBClient,
FMX.Controls.Presentation, FMX.TreeView, Data.Bind.DBScope, SimpleDS,
Data.Bind.Controls, FMX.ListBox, FMX.Grid.Style, FMX.Grid, FMX.ScrollBox,
FMX.Edit;
type
TMasterDetailForm = class(TForm)
Master: TSimpleDataSet;
Detail: TSimpleDataSet;
MasterMasterID: TIntegerField;
MasterName: TStringField;
DetailDetailID: TIntegerField;
DetailMasterID: TIntegerField;
DetailName: TStringField;
BindSourceMaster: TBindSourceDB;
NavigatorBindSourceDB1: TBindNavigator;
BindingsList1: TBindingsList;
BindGridLink1: TBindGridLink;
edMasterID: TEdit;
LinkControlToField1: TLinkControlToField;
edMasterName: TEdit;
LinkControlToField2: TLinkControlToField;
edDetailID: TEdit;
edDetailMasterID: TEdit;
edDetailName: TEdit;
LinkControlToField3: TLinkControlToField;
BindSourceDetail: TBindSourceDB;
LinkControlToField4: TLinkControlToField;
BindNavigator1: TBindNavigator;
DataSource1: TDataSource;
LinkControlToField5: TLinkControlToField;
procedure FormCreate(Sender: TObject);
procedure DetailNewRecord(DataSet: TDataSet);
procedure MasterNewRecord(DataSet: TDataSet);
private
public
NextMasterID,
NextDetailID : Integer;
end;
[...]
procedure TMasterDetailForm.FormCreate(Sender: TObject);
var
i,
j : Integer;
begin
Master.IndexFieldNames := 'MasterID';
Master.CreateDataSet;
Detail.IndexFieldNames := 'MasterID;DetailID';
Detail.CreateDataSet;
NextMasterID := 1;
NextDetailID := 1;
for i := 1 to 3 do begin
Master.Insert;
Master.Post;
for j := 1 to 3 do begin
Detail.Insert;
Detail.Post;
end;
end;
Master.First;
end;
procedure TMasterDetailForm.DetailNewRecord(DataSet: TDataSet);
begin
Detail.FieldByName('DetailID').AsInteger := NextDetailID;
Detail.FieldByName('MasterID').AsInteger := Master.FieldByName('MasterID').AsInteger;
Detail.FieldByName('Name').AsString := Format('DetailID:%d for MasterID:%d ', [NextDetailID, Master.FieldByName('MasterID').AsInteger]);
inc(NextDetailID);
end;
procedure TMasterDetailForm.MasterNewRecord(DataSet: TDataSet);
begin
Master.FieldByName('MasterID').AsInteger := NextMasterID;
Master.FieldByName('Name').AsString := 'Master' + IntToStr(NextMasterID);
Inc(NextMasterID);
end;
end.
DFM提取物
object MasterDetailForm: TMasterDetailForm
OnCreate = FormCreate
object NavigatorBindSourceDB1: TBindNavigator
DataSource = BindSourceMaster
end
object edMasterID: TEdit
end
object edMasterName: TEdit
end
object edDetailID: TEdit
end
object edDetailMasterID: TEdit
end
object edDetailName: TEdit
end
object BindNavigator1: TBindNavigator
DataSource = BindSourceDetail
end
object Master: TSimpleDataSet
Aggregates = <>
DataSet.MaxBlobSize = -1
DataSet.Params = <>
MasterFields = 'MasterID'
Params = <>
OnNewRecord = MasterNewRecord
Left = 64
Top = 32
object MasterMasterID: TIntegerField
FieldName = 'MasterID'
end
object MasterName: TStringField
DisplayWidth = 30
FieldName = 'Name'
Size = 30
end
end
object Detail: TSimpleDataSet
Aggregates = <>
DataSet.MaxBlobSize = -1
DataSet.Params = <>
FieldDefs = <>
IndexDefs = <
item
Name = 'DetailIndex1'
Fields = 'MasterID;DetailID'
end>
IndexName = 'DetailIndex1'
MasterFields = 'MasterID'
MasterSource = DataSource1
PacketRecords = 0
Params = <>
StoreDefs = True
OnNewRecord = DetailNewRecord
Left = 64
Top = 224
object DetailDetailID: TIntegerField
FieldName = 'DetailID'
end
object DetailMasterID: TIntegerField
FieldName = 'MasterID'
end
object DetailName: TStringField
DisplayWidth = 30
FieldName = 'Name'
Size = 30
end
end
object BindSourceMaster: TBindSourceDB
DataSource.AutoEdit = False
DataSet = Master
ScopeMappings = <>
end
object BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
object BindGridLink1: TBindGridLink
Category = 'Links'
SourceComponent = Master
ColumnExpressions = <
item
Name = 'Exp1'
ColumnName = 'IDColumn'
ColumnIndex = 0
SourceMemberName = 'ID'
ControlMemberName = 'IDColumn'
ParseCellExpressions = <>
FormatCellExpressions = <>
FormatColumnExpressions = <>
end>
PosControlExpressions = <>
PosSourceExpressions = <>
FormatControlExpressions = <>
ClearControlExpressions = <>
end
object LinkControlToField1: TLinkControlToField
Category = 'Quick Bindings'
DataSource = BindSourceMaster
FieldName = 'MasterID'
Control = edMasterID
Track = False
end
object LinkControlToField2: TLinkControlToField
Category = 'Quick Bindings'
DataSource = BindSourceMaster
FieldName = 'Name'
Control = edMasterName
Track = False
end
object LinkControlToField3: TLinkControlToField
Category = 'Quick Bindings'
DataSource = BindSourceDetail
FieldName = 'DetailID'
Control = edDetailID
Track = False
end
object LinkControlToField4: TLinkControlToField
Category = 'Quick Bindings'
DataSource = BindSourceDetail
FieldName = 'MasterID'
Control = edDetailMasterID
Track = False
end
object LinkControlToField5: TLinkControlToField
Category = 'Quick Bindings'
DataSource = BindSourceDetail
FieldName = 'Name'
Control = edDetailName
Track = False
end
end
object BindSourceDetail: TBindSourceDB
DataSet = Detail
ScopeMappings = <>
end
object DataSource1: TDataSource
DataSet = Master
end
end