Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a custom control with a sub-panel that accepts other controls at designtime? [duplicate]

I have written a custom control, that has several sub panels. I want these sub panels to accept any additional controls dropped on them at design time.

Unfortunately any control that gets dropped at design time ends up on my custom control, not on the panels. This shows in particular if I try to drop a label: The label's blue dots are shown, but it's caption isn't and if I deselect the label, it is no longer visible at all.

simplified code (only one sub panel):

type
  TMyContainer = class(TPanel)
    p_SubPanel: TPanel;
  public
    constructor Create(_Owner: TComponent); override;
  end;

  constructor TMyContainer.Create(_Owner: TComponent);
  begin
    inherited;
    p_SubPanel := TPanel.Create(Self);
    p_SubPanel.Parent := Self;
    p_SubPanel.Align := alClient;
  end;

What am I doing wrong here?

(Just in case it matters: I am using Delphi 2007.)

[edit]

I have now solved it differently. The component no longer contains panels but refers to external panels. This makes it actually much more flexible, but on the downside it is no longer as intuitive to use.

I would still like to know how to accomplish what I described originally. Isn't there an open source component somewhere that does this, so I can study the source code?

like image 947
Thomas Mueller Avatar asked Dec 17 '08 12:12

Thomas Mueller


2 Answers

This is a good question. You can allow your custom TWinControl to have other controls dropped on it at design-time by adding csAcceptControls to your controls ControlStyle property.

constructor TMyContainer.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle := ControlStyle + [csAcceptControls];
end;

But in trying to work this out, I've had little success with being able to drop controls onto a sub panel within a custom control. Adding csAcceptControls to a sub panel's ControlStyle isn't enough. The cloest I've gotten is a hack to convince the sub panel it's being designed like so:

type
  TGiveMeProtected_Component = class(TComponent);

procedure TMyContainer.Create(AOwner: TComponent);
begin
  FSubPanel := TPanel.Create(Self);
  TGiveMeProtected_Component(FSubPanel).SetDesigning(True, True);
end;

Using that code, you can now drop controls onto the sub panel, but it means you can also select the sub panel, change it's properties and even delete it which you definately don't want. Sorry I couldn't come up with the answer, I'd still love to know if you work it out. :)

like image 167
CodeAndCats Avatar answered Oct 17 '22 05:10

CodeAndCats


I cant tell from the details, but are you setting the parent of the label to you sub panel? If its at design time you may need to write code in your main component (eg the container that your panels are in), to figure out which subpanel is accepting the component and set the labels parent property to that subpanel.

I'm pretty sure the a notification method gets called when a component is added or removed from another component, this should help you track down where you need to put the code.

like image 23
Toby Allen Avatar answered Oct 17 '22 06:10

Toby Allen