1

Я новичок в разработке компонентов в Delphi, поэтому хочу знать, возможно ли вообще реализовать мою задачу.Возможно ли это? TCollection потомка для реализации хранения контейнеров TPanel с произвольным контентом

Мне нужно создать визуальный компонент (пользовательский контроль) на основе TScrollBox, который будет представлять собой группу TPanel, все панели будут выровнены как «Top» внутри этого TScrollBox и могут иметь разную высоту. Он должен действовать как TCollection (добавить, удалить, изменить порядок) и должен позволить пользователям добавлять другие элементы управления в эти панели в режиме разработки.

Я создал эти классы для компонента:

type 
    TPanelsGrid = class; 

    TPanelsGridItem = class(TCollectionItem) 
    private 
    FPanel: TPanel; 
    procedure SetPanel(Value: TPanel); 
    function GetGrid: TPanelsGrid; 
    protected 
    function GetDisplayName: string; override; 
    public 
    constructor Create(Collection: TCollection); override; 
    destructor Destroy; override; 
    procedure Assign(Source: TPersistent); override; 
    published 
    // This is my TPanel object that should be used at designtime 
    // I thought "stored True" will serialize it automatically but I was wrong 
    property Panel: TPanel read FPanel write SetPanel stored True; 
    end; 

    TPanelsGridItems = class(TCollection) 
    private 
    FPanelsGrid: TPanelsGrid; 
    protected 
    function GetItem(Index: Integer): TPanelsGridItem; 
    procedure SetItem(Index: Integer; Value: TPanelsGridItem); 

    function GetOwner: TPersistent; override; 
    procedure Update(Item: TCollectionItem); override; 
    public 
    property EditorsGrid: TPanelsGrid read FPanelsGrid; 
    property Items[Index: Integer]: TPanelsGridItem 
     read GetItem write SetItem; default; 

    constructor Create(PanelsGrid: TPanelsGrid); 
    function Add: TPanelsGridItem; 
    procedure Delete(Index: Integer); 
    end; 

    TPanelsGrid = class(TScrollBox) 
    private 
    FItems: TPanelsGridItems; 
    procedure SetItems(Value: TPanelsGridItems); 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
    published 
    property Items: TPanelsGridItems read FItems write SetItems; 
    end; 

Этот компонент работает нормально на этапе проектирования, я могу добавить, удалить панели в стеке, когда я снижается некоторый контроль (например, TCheckbox) на любом панели, он отображается как «принадлежащий этой панели»: например, Я не могу перетащить этот флажок из панели.

Но этот флажок не хранится в DFM-файле и не отображается в окне «Структура».

Я предполагаю, что должна быть какая-то ручная сериализация-десериализация содержимого TPanel, но я не знаю, как это сделать. Невозможно найти какой-либо пример в Интернете. Plase дать мне некоторые рекомендации, если такая реализация возможна вообще.

Добавление:

Это как мой фрагмент DFM-файл выглядит после добавления 3 панелей в сеть:

object PanelsGrid1 : TPanelsGrid 
    Left = 8 
    Top = 8 
    Width = 536 
    Height = 382 
    Anchors = [akLeft, akTop, akRight, akBottom] 
    TabOrder = 0 
    Items = < 
     item 
     end 
     item 
     end 
     item 
     end> 
    end 

Как вы можете видеть, все элементы являются пустыми, но я упал там checkbox и radiobutton в пункт № 3.

+0

Щелкните правой кнопкой мыши форму во время разработки и выберите «Просмотреть как текст». Найдите часть, связанную с вашим компонентом, и добавьте ее в свой пост, если вы не возражаете. Я не уверен, как это тоже должно быть реализовано, но давайте посмотрим, что хранится в первую очередь. – himself

+0

Опубликованные свойства, унаследованные от TComponents, не сохраняются системой потоковой передачи. –

+0

сам, сделано, PLS посмотреть на dfm. – Andrew

ответ

1

В конце концов, я решил отказаться от использования TCollection, потому что во время тестирования метода DefineProperties у меня последовательная сбой IDE. Я думаю, что TCollection просто не был предназначен для такой задачи.

Я основал соответствующую реализацию внутри источников Delphi внутри элемента управления ExtCtrls.TCustomCategoryPanelGroup. Он поддерживает стек панелей, которые можно добавлять или удалять как во время разработки, так и во время выполнения. Я создал свои собственные классы, используя исходный код TCustomCategoryPanelGroup и TCustomCategoryPanel, и он работает так, как я хочу.

0

Я думаю, вы можете посмотреть на TMS Poly List control

Компоненты TMS Advanced Poly Список предлагают чрезвычайно универсальный и гибкую архитектуру для создания практически любые возможные списки элементов в пользовательских интерфейсах. Это видно из , как правило, но не ограничиваясь новым меню приложений Office 2010. В отличии от большинства пользовательского интерфейса управления списка, где список состоит из пунктов же типа или коллекции предметов того же типа, компоненты Списка TMS Advanced Poly могут содержать PolyMorph пунктов. Все элементы просто должны спуститься от базового класса TCustomItem и любые наследуемые элементы могут быть добавлены. компонентов TMS Advanced Poly Списка приходят с большим набором предварительно построенного список элементов, но классы пользовательского элемента может быть добавлены либо нисходящим TCustomItem базового класса или любым из классов, которые уже предусмотрен. Есть классы предметов, которые следует показать в виде списка item, text item with HTML formatting, текст с кнопками, item с expand/collaps поведение, item с и многие другие. Элементы могут быть добавлены в полиморфные списки либо по адресу времени разработки, с богатым временем разработки редактор и во время выполнения по коду.

+0

Спасибо. Жаль, что он закрыл исходный код. Но если я не найду решение в своем собственном коде, обязательно подумайте о покупке. – Andrew

0

Убедитесь, что у ваших детских панелей есть имена. Вы можете переопределить TCollection.Notify и если Action cnAdded, убедитесь, что у панели есть имя.