Bascy
Bascy

Reputation: 2089

Restrict list of components when linking in property editor in IDE

I have created a new designtime component, which contains a published property Handler of type TComponent and registered it into the Tool Palette.

When i place a component of this type on my form, the property editor of the IDE shows me the property 'Handler' with a dropdown box that allows me to set this property at design time. The dropbox shows all available TComponents on the current form.

How can I restrict the list of components that is shown here (design time) to components of a certain type or with a certain property? i.e. Components that implement a certain (set of) interfaces.

I know that you can also use interface-properties, but also encountered several posts on the internet stating that this is very unstable and raises all kinds of problems.

Is there a method I can call for each of the proposed components where I can determine if they should appear in the list at design time?

Addition after the answer of @David:
Now that I've learned that TComponentProperty is what i was looking for, I also found a related question here: How to modify TComponentProperty to show only particular items on drop down list?

Upvotes: 0

Views: 352

Answers (2)

David Heffernan
David Heffernan

Reputation: 612954

  1. Derive a sub class of TComponentProperty.
  2. Override its GetValues method to apply your filter.
  3. Register this TComponentProperty as the property editor for your property.

Here is a very simple example:

Component

unit uComponent;

interface

uses
  System.Classes;

type
  TMyComponent = class(TComponent)
  private
    FRef: TComponent;
  published
    property Ref: TComponent read FRef write FRef;
  end;

implementation

end.

Registration

unit uRegister;

interface

uses
  System.SysUtils, System.Classes, DesignIntf, DesignEditors, uComponent;

procedure Register;

implementation

type
  TRefEditor = class(TComponentProperty)
  private
    FGetValuesProc: TGetStrProc;
    procedure FilteredGetValuesProc(const S: string);
  public
    procedure GetValues(Proc: TGetStrProc); override;
  end;

procedure TRefEditor.FilteredGetValuesProc(const S: string);
begin
  if S.StartsWith('A') then
    FGetValuesProc(S);
end;

procedure TRefEditor.GetValues(Proc: TGetStrProc);
begin
  FGetValuesProc := Proc;
  try
    inherited GetValues(FilteredGetValuesProc);
  finally
    FGetValuesProc := nil;
  end;
end;

procedure Register;
begin
  RegisterComponents('Test', [TMyComponent]);
  RegisterPropertyEditor(TypeInfo(TComponent), nil, 'Ref', TRefEditor);
end;

end.

This rather useless property editor will only offer you components whose names begin with A. Despite its complete lack of utility, this does illustrate the ability to filter that you desire. You'll likely want to call Designer.GetComponent(...) passing a component name to obtain the component instance, and implement your filtering based on the type and state of that component instance.

Upvotes: 4

SilverWarior
SilverWarior

Reputation: 8331

As @TLama already pointed out you need to change the tpe of handler field/property.

Now in case if you want to ba able to assign specific type of component to this field/property then set this field type to the same type of that compomnent.

But if you want to be able to assign several different component types but not all components make sure that Handler field/property type is the type of the first common ancestor class/component of your desired components that you want to be able to assign to the Handler field/property.

Upvotes: -1

Related Questions