Search code examples
delphicomponentsfiremonkeycustom-componentdelphi-10.1-berlin

Custom Firemonkey Component that implements TComponentEditor. Add child control to parent at design time


I have a custom FireMonkey control (TComboBox) that also has a custom TComponentEditor. When I override the ExecuteVerb method and attempt to add a child component (custom TListBoxControl) the custom TComboBox it does not get shown at design time

Default TComboBox Behavior:

Default TComboBox behavior

Custom TComboBox

Custom TComboBox

My ExecuteVerb Code:

var
  PpComboItem : TPpListBoxItem;
  PpCombo: TPpComboBox;
begin
  if (Component is TPpComboBox) then
    PpCombo := (Component as TPpComboBox) else
      exit;

  PpComboItem := TPpListBoxItem.Create(PpCombo);
  PpComboItem.Parent := PpCombo;
end

I've tried to trace the way the TComboBox tries to do this but cant seem to find the unit with the correct implementation

** Edit **

Okay - I've managed to have a look at how the guys from TMS achieved this with their components (bought and paid for) and I've managed to extrapolate the following

var
  PpComboItem : TPpListBoxItem;
  PpCombo: TPpComboBox;
begin
  inherited;
  if (Component is TPpComboBox) then
    PpCombo := (Component as TPpComboBox) else
      exit;

  PpComboItem := (TPpListBoxItem(Designer.CreateComponent(TPpListBoxItem,  PpCombo, 10, 10, 100, 100)));
  PpComboItem.Parent := PpCombo;
  Designer.Modified;
end;

But when I click the AddTPpListBoxItem in the ComponentEditor I get the following error:

Class TPpListBoxItem is not applicable to this module


Solution

  • I've found my answer. To get this working you need to

    Make sure the component that you're trying to add as a child to the parent is also registered:

    USES TPpListBoxItem.pas, TPpComboBox.pas, DesignIntf, DesignEditors
    
    //TComponentEditor Type Decleration //
    
    procedure Register;
    begin
      RegisterComponents('Sample', [TPpListBoxItem]);
      RegisterComponents('Sample', [TPpComboBox]);
      RegisterComponentEditor(TPpComboBox, TComboComponentEditor);
    end;
    

    Override the ExecuteVerb method of the TComponentEditor of the Parent Component (find the code in my question where the first edit is):

    Basically the meat is:

    ...
    PpComboItem := (TPpListBoxItem(Designer.CreateComponent(TPpListBoxItem, PpCombo, 10, 10, 100, 100)));
    PpComboItem.Parent := PpCombo;
    Designer.Modified;
    ...
    

    Voila!