2014-12-25 4 views
2

Я использую RAD Studio XE5 для создания моего приложения.Класс свойств компонента Delphi в зависимости от класса владельца компонента

Я видел, что было не очень практично пытаться опубликовать свойства на TForm. Затем он должен быть зарегистрирован и установлен как пакет, тогда он не практичен для интенсивного развития.

Итак, я решил создать не визуальный компонент (TFormPropertiesEditor), который будет использоваться для заполнения свойств формы. Способ стандартизации моих форм.

Компонент будет опущен на базовую форму, форма которой наследует любую другую форму (назовем ее TBaseForm). Итак, компонент будет сброшен только один раз на «базовую» форму, то с наследованием каждая другая форма тоже будет иметь его.

Созданный компонент будет определять класс своего владельца (BaseForm или его потомков) и создать объект, доступный через свойство «Свойства», класс которого будет относиться к классу владельца.

Таким образом, при проверке компонента на TBaseForm у меня будет доступ только к TBaseFormProperties. При проверке компонента в TSecondForm у меня также был бы доступ к TSecondFormProperties. Только, компонент был бы достаточно интеллектуальным, чтобы определить, какой PropertyClass он должен выставить как свойство Свойства.

Компонент бы проверить форму, через GetPropertiesClass, определяется как:

function TBaseForm.GetPropertiesClass : TPropertiesClass; 
begin 
    Result := TBaseFormProperties; 
end; 

function TSecondForm.GetPropertiesClass : TPropertiesClass; 
begin 
    Result := TSecondFormProperties; 
end; 

Каждая форма имеет соответствующие TProperties потомка, например, так:

TBaseForm ------------ TSecondForm ------------- ... 
    | 
TBaseFormProperties -- TSecondFormProperties --- ... 

Например:

Если форма, на которой размещен компонент, является TBaseForm, FProperties будет TBaseFormProperties. Если форма является TSecondForm, FProperties будет TSecondFormProperties. Естественно, TSecondFormProperties наследуется от TBaseFormProperties.

Хотя, когда я помещаю компонент в форму, кажется, не удается определить, в каком классе этот компонент.

function TFormPropertiesEditor.GetPropertiesClass: TFormPropertiesClass; 
begin 
    Result := TBaseForm(Owner).GetPropertiesClass; 
end; 

Похоже, что проблема с TBaseForm (Владелец) вызывает проблему. Интерпретатор застрял в TBaseForm и не будет учитывать, имеет ли Owner тип TSecondForm или TThirdForm.

Интерфейсы

Так, чтобы обойти TBaseForm (Владелец) типажей, я решил использовать интерфейс. Так что, если я использую интерфейс, который декларирует GetPropertiesClass:

IMasterForm = interface(IInterface) 
    ['{B6122F34-65C4-4701-8A5E-50C8DABF5516}'] 
    function GetPropertiesClass : TFormPropertiesClass; 
    end; 


type 
    TBaseForm = class(TForm, IMasterForm) 
    MyFormPropertiesEditor1: TMyFormPropertiesEditor; 
    private 
    { Déclarations privées } 
    public 
    function GetPropertiesClass : UCommon.TFormPropertiesClass; 
    end;  

Ниже:

function TFormPropertiesEditor.GetPropertiesClass : TFormPropertiesClass; 
begin 
    Result := (Owner as IMasterForm).GetPropertiesClass; 
end; 

Результаты в интерфейс не поддерживается ошибка.

Аннотация предок Метод

Тогда я решил добавить дополнительный слой родословной. Я добавил класс, TMasterForm, из которого наследуется TBaseForm. Это TMasterForm объявляет GetPropertiesClass, как абстрактные и виртуальные:

TMasterForm = class(TForm, IMasterForm) 
    public 
     function GetPropertiesClass : TFormPropertiesClass; virtual; abstract; 
    end; 


type 
    TBaseForm = class(TMasterForm) 
    private 
    { Déclarations privées } 
    public 
    function GetPropertiesClass : UCommon.TFormPropertiesClass; override; 
    end; 

Но тогда, я получаю AV, потому что я думаю, что IDE пытается получить доступ к TMasterClass.GetPropertiesClass, которая, конечно, не реализуется.

Как можно выполнить этот TypeCasting? Любая идея, как я могу продолжить?

Большое спасибо заранее

Скачать Sample Projecthttps://www.wetransfer.com/downloads/b524438609fc04257af803a8e3dd2eca20141225161239/764d108d335b9d296c3004dfea04a54620141225161240/9c8cc0

+0

Вы не зарегистрировали свою базовую форму с помощью IDE. Таким образом, во время разработки форма, которую вы видите, не относится к типу 'TBaseForm'. То, что вы пытаетесь, не сработает. Я думаю, что вся твоя работа напрасна. Вернуться к доске для рисования. –

+0

Возможно, вам нужно ['RegisterCustomModule'] (http://www.marcocantu.com/ddh/ddh15/ddh15e.htm) ... –

+0

@DavidHeffernan Я не думаю, что он делает это неправильно. Никакие специальные редакторы определенных элементов не используют подобный подход. – SilverWarior

ответ

2

Основная проблема заключается в том, что IDE не создает экземпляр формы во время разработки. Таким образом, независимо от того, какой код вы введете в класс формы, он не будет выполнен с помощью IDE. Это связано с тем, что вы не зарегистрировали форму с помощью IDE.

Если вы хотите, чтобы IDE знала ваши формы, вам необходимо зарегистрировать их в среде IDE. И в этот момент весь ваш код становится ненужным, потому что вы вернулись к тому, что пытаетесь избежать. А именно, регистрацию форм с помощью IDE. Вы застряли в ситуации Catch 22. Если вам нужна IDE, чтобы узнать о формах, вам необходимо их зарегистрировать. В этот момент вы можете просто перенести свойства непосредственно в Object Inspector.

-1

Проблема в коде является то, что вы не наследуя ваш метод GetPropertiesClass правильно.

Infact, вы не наследуете его по классу семьи.

В вашем коде каждый тип класса имеет свою собственную версию метода GetPropertiesClass, поэтому, поскольку вы управляете владельцем классом TBaseForm, метод из TBaseForm используется, даже если Owner имеет класс TSecondForm.

Итак, вы должны убедиться, что класс GetPropertiesClass в классе TBaseForm является виртуальным и что merhod GetPropertiesClass в TSecondForm переопределяется.

Это гарантирует, что метод TSecondForm.GetProperties будет вызываться, даже если вы являетесь typginging Owner to TBaseClass, когда владелец имеет класс TSeconfForm.

+0

Спасибо за ваш ответ. Я действительно это сделал. Я даже добавил еще один класс, TMasterForm = class (TForm), который имеет абстрактную и виртуальную версию GetPropertiesClass, из которой наследуется TBaseForm. TBETForm's GetPropertiesClass объявлен завышенным. Тем не менее, когда я удаляю компонент в форме, среда IDE теперь пытается получить доступ к GetPropertiesClass TMasterForm, что приводит к AV, поскольку этот метод является абстрактным. – Ludo

Смежные вопросы