2008-12-17 9 views
6

He escrito un control personalizado, que tiene varios subpaneles. Quiero que estos subpaneles acepten cualquier control adicional que se les deje caer en el momento del diseño.¿Cómo creo un control personalizado con un subpanel que acepta otros controles en designtime?

Lamentablemente, cualquier control que se caiga en el momento del diseño termina en mi control personalizado, no en los paneles. Esto muestra, en particular, si trato de soltar una etiqueta: se muestran los puntos azules de la etiqueta, pero su leyenda no aparece y, si anulo la selección de la etiqueta, ya no estará visible.

código simplificado (solo un panel secundario):

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; 

¿qué estoy haciendo mal aquí?

(Sólo en caso de que importe: Estoy utilizando Delphi 2007.)

[editar]

ahora lo he resuelto de manera diferente. El componente ya no contiene paneles sino que se refiere a paneles externos. Esto lo hace mucho más flexible, pero a la baja ya no es tan intuitivo de usar.

Todavía me gustaría saber cómo lograr lo que describí originalmente. ¿Hay algún componente de código abierto en alguna parte que lo haga así que puedo estudiar el código fuente?

Respuesta

1

No sé por los detalles, pero ¿está configurando el elemento primario de la etiqueta para su subpanel? Si es en el momento del diseño, es posible que deba escribir código en su componente principal (por ejemplo, el contenedor en el que se encuentran sus paneles), para determinar qué subpanel acepta el componente y establecer las propiedades padre de las etiquetas en ese subpanel.

Estoy bastante seguro de que se llama a un método de notificación cuando se agrega o elimina un componente de otro componente, esto debería ayudarlo a localizar dónde debe colocar el código.

2

Esta es una buena pregunta. Puede permitir que su TWinControl personalizado tenga otros controles en él en tiempo de diseño agregando csAcceptControls a su propiedad ControlStyle de controles.

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

Pero al tratar de resolver esto, he tenido poco éxito con ser capaz de soltar los controles en un panel secundario dentro de un control personalizado. Agregar csAcceptControls al ControlStyle de un subpanel no es suficiente. El cloest que he recibido es un truco para convencer al panel secundario que está siendo diseñado de esta manera:

type 
    TGiveMeProtected_Component = class(TComponent); 

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

El uso de ese código, ahora se puede colocar controles en el panel secundario, pero significa también puede seleccionar el sub panel, cambiar sus propiedades e incluso eliminarlo que definitivamente no desea. Lamento no poder encontrar la respuesta, todavía me gustaría saber si lo resuelves. :)

0

Lo hice, pero terminé reemplazando los controles con paneles regulares que se mostrarían/​​ocultarían cuando fuera necesario.

En lugar de descender de TPanel, mis controles descienden de TCustomControl. No creo que pueda hacer que funcione desde TPanel, pero no recuerdo cuál fue el problema.

El control contenedor:

TPageControl = class(TCustomControl) 
private 
    PageList:TObjectList; // To hold references to all sub-pages for easy access. 
end; 

constructor TPageControl.Create(AOwner: TComponent); 
begin 
    inherited; 
    ControlStyle := ControlStyle + [csAcceptsControls]; 
    PageList := TObjectList.Create; 
    PageList.OwnsObjects := false; 
end; 

destructor TVstPageControl.Destroy; 
begin 
    PageList.Free; 
    inherited; 
end; 

procedure TPageControl.NewPage; 
var 
    Page:TPage; 
begin 
    Page := TPage.Create(Self.Owner); 
    Page.Parent := Self; 
    Page.Align := alClient; 

    PageList.Add(Page); 
end; 

procedure TPageControl.DeletePage(Index:integer); 
var 
    Page:TPage; 
begin 
    Page := PageList[Index] as TPage; 
    Page.Free; 
    PageList.Delete(Index); 
end; 

El control de página/subpanel:

TVstPage = class(TCustomControl) 
public 
    constructor Create(AOwner: TComponent); override; 
end; 

constructor TPage.Create(AOwner: TComponent); 
begin 
    inherited; 
    ControlStyle := ControlStyle + [csAcceptsControls]; 
end; 
Cuestiones relacionadas