Hide some non visual controls at edit form

Hello


I am trying to hide some visual controls when editing a form. I try to do that through

property OnComponentEditable: TComponentEditableEvent from TAdvCustomFormDesigner but the event is protected and I can not create/access to that object to create my own inherited because is hard created at the TIDEFormDesignControl.Create(AOwner: TComponent) constructor.

Sure there is a easy way to do that but can not find how...just want to declare the invisible controls p.e.

hide_component(myclass1);
hide_component(myclass2);

or get an event fired when oncomponentEditable or OnIsComponenVisible ocurrs

All the best
ilde

You need the component to be invisible? Or just not editable?

If invisible, can't you just remove them from the form temporarily?

Thank you for the reply.


some 3d party components that I use have internal non visual components that belongs to the form so I cant deal with them. I would like to hide these components from the form in design time so the user can not click or view they. Fantastic if I could hide by class name.

all the best
ilde

You can access the underlying Form Designer object using the TIDEEngine.Designer property. Indeed the method is protected, we will update source code here to make all events public. But in the meanwhile, you can use a hack to access that protected event.

Thank you!


I will do...maybe could be better to add an event hook 

procedure OnShowComponent(const aSender : TObject; const aComponent : TComponent; var visible = true);

or something like that

All the best
ilde

Isn't OnComponentEditable what you are looking for?

From the Engine can not access to the Designer when I try to set the event because is always nil at initialization so I think is better to make use of class inheritance to set the event in the constructor.


A solution could be:

file IDEMain line 2886 avoid the hard class creation using a factory class creation

FDesigner := TIDEFormDesigner.Create(nil);

change to:

FDesigner := GetIDEFormDesignerClass.Create(nil);
...
TIDEFormDesignerClass = class of TIDEFormDesigner;

function GetIDEFormDesignerClass : TIDEFormDesignerClass;
begin
result := TMyIDEFormDesignerClass;
end;

where TMyIDEFormDesignerClass = class(TIDEFormDesigner)

so a new IDEFormDesigner could be used instead the original one. 

A more elegant solution could be achive using interfaces but I dont think could be a good idea mix class and interfaces programing techniques at the same code at this time.

All the best
ilde

Sorry....I sent the previous solution incomplete:


At IDEMain add:

TIDEFormDesignerClass = class of TIDEFormDesigner;

At protected section in TIDEFormDesignControl add

function GetIDEFormDesignerClass : TIDEFormDesignerClass; virtual;

At the constructor of TIDEFormDesignControl replace the hard creation:

FDesigner := GetIDEFormDesignerClass.Create(nil);

Add the normal function to normal behaivour

function TIDEFormDesignControl.GetIDEFormDesignerClass: TIDEFormDesignerClass;
begin
  result := TIDEFormDesigner;
end;

With these modifications now you could be able to create your own IDEFormDesignControl as shown at the next code:

unit st4makers.IDE.MyFormDesignComponent;

interface

uses
  Classes,  IDEMain;

type
  TMyIDEFormDesigner = class(TIDEFormDesigner)
  private
    procedure MyComponentEditable(Sender: TObject; TheComponent: TComponent;
    var Editable: boolean);
  public
    constructor Create(Owner : TComponent); override;
  end;

  TMyIDEFormDesignComponent = class(TIDEFormDesignControl)
  protected
    function GetIDEFormDesignerClass : TIDEFormDesignerClass; override;
  public
    constructor Create(Owner: TComponent); override;
  end;

implementation

{ TMyIDEFormDesignComponent }

constructor TMyIDEFormDesignComponent.Create(Owner: TComponent);
begin
  inherited;
end;

function TMyIDEFormDesignComponent.GetIDEFormDesignerClass: TIDEFormDesignerClass;
begin
  result := TMyIDEFormDesigner;
end;

{ TMyIDEFormDesigner }

constructor TMyIDEFormDesigner.Create(Owner: TComponent);
begin
  inherited;

  OnComponentEditable := MyComponentEditable;
end;

procedure TMyIDEFormDesigner.MyComponentEditable(Sender: TObject;
  TheComponent: TComponent; var Editable: boolean);
begin

end;

end.

dont forget to make public
    property OnComponentEditable: TComponentEditableEvent
      read FOnComponentEditable write FOnComponentEditable;

or make virtual protected a DoComponentEditable

All the best
ilde

What you mean by "initialization" where designer is always nil? As soon as TIDEEngine.FormDesignControl is set, the designer is available. I should be very simple to get a point where it would be available.

There is a setter that I could use 


procedure TMyIDEEngine.SetDesignControl(const Value: TIDEFormDesignControl);
begin
  inherited DesignControl := Value;

if Value <> nil then
   DesignControl.FDesigner.OnComponentEditable .... //error FDesigner is private
end;

but FDesigner is private so it should be exposed public....but I think is better to do the factory creation method

All the best
ilde

You don't need that. Just read TIDEEngine.Designer property.


Thank you!

It worked. I have not seen that property!

Please, consider to change the hard creation of the IDEFormDesignerClass at the TIDEFormDesignControl.create to use a personal TIDEFormDesigner ... it is extrange for me to set a event hook in the setter procedure

Thank you a lot for the great support
ilde