Если я правильно понимаю, что вы спрашиваете, я думаю, что проект ниже покажет вам самые важные вещи о добавлении записей Master + Detail. Я думаю, что TListViews на самом деле отвлекают от понимания того, что необходимо, поэтому я собираюсь пропустить их и вместо этого использовать некоторые TEdits для отображения записей Master + Details по очереди.
По моему опыту Основное правило - избегать использования чего-либо с использованием LiveBindings, если есть более простой способ сделать это, и это тот случай, когда речь идет об установлении отношения Master-> Detail между Master и Details.
Итак, среди списка компонентов в форме есть TDataSource, который связывает их. Его свойство DataSet связано с мастером; на стороне детализации свойство MasterSource детализации должно быть установлено на него, а его свойство MasterField установлено в поле MasterID мастера.
Смысл добавления TDataSource заключается в том, что он позволяет использовать стандартную модель TDataset и события он поддерживает выполнение всей работы, необходимой для установления связи между новой записью сведений при ее вставке и текущей MasterRecord. Это делается в событии OnNewRecord объекта Detail, которое выглядит следующим образом:
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 заключается в том, что он гарантирует правильную синхронизацию мастера и детали при вставке новой записи детали. .
Единственный другой код подписи находится в 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