2008-12-17 8 views
6

Tôi đã viết một điều khiển tùy chỉnh, có một số bảng phụ. Tôi muốn các bảng phụ này chấp nhận bất kỳ điều khiển bổ sung nào rơi vào chúng khi thiết kế.Làm cách nào để tạo điều khiển tùy chỉnh với bảng phụ có chấp nhận các điều khiển khác tại thời gian designtime?

Thật không may bất kỳ kiểm soát nào bị giảm vào lúc thiết kế kết thúc trên điều khiển tùy chỉnh của tôi, không phải trên bảng điều khiển. Điều này cho thấy đặc biệt nếu tôi cố gắng để thả một nhãn: Các dấu chấm màu xanh của nhãn được hiển thị, nhưng chú thích của nó không phải là và nếu tôi bỏ chọn nhãn, nó không còn nhìn thấy được nữa.

đang đơn giản (chỉ có một bảng phụ):

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; 

Tôi đang làm gì sai ở đây?

(Chỉ trong trường hợp quan trọng: Tôi đang sử dụng Delphi 2007.)

[sửa]

bây giờ tôi đã giải quyết nó một cách khác. Thành phần không còn chứa các bảng nhưng đề cập đến các bảng bên ngoài. Điều này làm cho nó thực sự linh hoạt hơn nhiều, nhưng mặt khác nó không còn trực quan để sử dụng nữa.

Tôi vẫn muốn biết cách hoàn thành những gì tôi mô tả ban đầu. Không phải là có một thành phần nguồn mở ở đâu đó mà làm điều này, vì vậy tôi có thể nghiên cứu mã nguồn?

Trả lời

1

Tôi không thể biết được chi tiết, nhưng bạn có đặt cha mẹ của nhãn cho bảng phụ không? Nếu tại thời điểm thiết kế, bạn có thể cần phải viết mã trong thành phần chính của bạn (ví dụ như vùng chứa bảng của bạn), để tìm ra subpanel nào chấp nhận thành phần và đặt thuộc tính cha của nhãn cho bảng con đó.

Tôi khá chắc chắn rằng phương thức thông báo được gọi khi một thành phần được thêm vào hoặc bị xóa khỏi thành phần khác, điều này sẽ giúp bạn theo dõi vị trí bạn cần đặt mã.

2

Đây là một câu hỏi hay. Bạn có thể cho phép TWinControl tùy chỉnh của bạn có các điều khiển khác được thả vào lúc thiết kế bằng cách thêm csAcceptControls vào thuộc tính ControlStyle của điều khiển của bạn.

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

Nhưng khi cố gắng thực hiện điều này, tôi đã có rất ít thành công với việc có thể thả điều khiển vào bảng điều khiển phụ trong một điều khiển tùy chỉnh. Việc thêm csAcceptControl vào ControlStyle của bảng điều khiển phụ là không đủ. Các cloest tôi đã nhận được là một hack để thuyết phục các bảng phụ nó được thiết kế như sau:

type 
    TGiveMeProtected_Component = class(TComponent); 

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

Sử dụng mã mà, bây giờ bạn có thể thả các điều khiển trên bảng phụ, nhưng nó có nghĩa là bạn cũng có thể chọn phụ bảng điều khiển, thay đổi thuộc tính của nó và thậm chí xóa nó mà bạn chắc chắn không muốn. Xin lỗi tôi không thể đưa ra câu trả lời, tôi vẫn muốn biết nếu bạn làm việc đó. :)

0

Tôi đã làm điều này, nhưng cuối cùng thay thế các điều khiển bằng các bảng thông thường sẽ được hiển thị/ẩn khi được yêu cầu.

Thay vì giảm dần từ TPanel, các điều khiển của tôi xuất phát từ TCustomControl. Tôi không nghĩ rằng tôi có thể làm cho nó hoạt động giảm dần từ TPanel nhưng không thể nhớ vấn đề là gì.

Việc kiểm soát container:

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; 

Trang/sub-control panel:

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

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