Let's say we have a visual project with main form MainForm and dialog AddDialog. The main form contains a listbox lbItems and the dialog contains a wrapper panel W3Panel1 with three child objects - an edit box inpItem and two buttons - btnOK and btnCancel. The AddDialog dialog is registered with a name AddDialog.
FAddDialog := TAddDialog.Create(Display.View);
FAddDialog.Name := 'AddDialog';
RegisterFormInstance(FAddDialog, False);
The dialog is then displayed with a simple ShowModal call.
btnAdd.OnClick := lambda
Application.ShowModal('AddDialog', 'W3Panel1', 'inpItem', InitDialog, OkResponse);
end;
The simplest way to access the main form's listbox from the dialog is to provide the dialog with the reference to the main form's component. To do so, add a property to the dialog
property Items: TW3ListBox;
and then assign its value in the InitDialog.
procedure TMainForm.InitDialog(dialog: TW3CustomForm);
begin
(dialog as TAddDialog).Items := lbItems;
end;
In the dialog itself you can then set up button click handlers.
btnCancel.OnClick := lambda Application.HideModal(mrCancel); end;
btnOK.OnClick := lambda CloseDialog; end;
The CloseDialog method will check whether the edit box is empty or equal to an already existing item in the listbox. You are correct that the IndexOf method is of no use in this case so just use a for loop to check all listbox items.
procedure TAddDialog.CloseDialog;
begin
if inpItem.Text = '' then
Exit;
for var i := 0 to Items.Count - 1 do
if Items.Text[i] = inpItem.Text then
Exit;
Application.HideModal(mrOK);
end;
BTW, the best way to access the dialog edit box from the main form is to expose it via a property in the dialog object:
property ItemText: string read (inpItem.Text) write (inpItem.Text);
The code in the main program can then access this property.
procedure TMainForm.OkResponse(dialog: TW3CustomForm);
begin
lbItems.Add((dialog as TAddDialog).ItemText);
end;