Класс свойств компонента Delphi в зависимости от класса владельца компонента



Я использую RAD Studio XE5 для сборки своего приложения.



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



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

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



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

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



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



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

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


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



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


Для пример:



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



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

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


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



Интерфейсы



Итак, чтобы обойти типизацию TBaseForm (Owner), я решил использовать интерфейс. Поэтому, если я использую интерфейс, который объявляет 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, который, конечно же, не реализован.



Как можно осуществить эту типизацию? Есть идеи, как мне действовать дальше ?



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



Скачать Пример Проекта https://www.wetransfer.com/downloads/b524438609fc04257af803a8e3dd2eca20141225161239/764d108d335b9d296c3004dfea04a54620141225161240/9c8cc0

568   2  

2 ответов:

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

Если вы хотите, чтобы IDE знала о ваших формах, вам нужно зарегистрировать их в IDE. И в этот момент весь ваш код становится ненужным, потому что вы возвращаетесь к тому, чего вы пытаетесь избежать. А именно регистрация бланков с помощью ИНТЕГРИРОВАННАЯ СРЕДА РАЗРАБОТКИ. Вы застряли в ситуации Уловки 22. Если вам нужно, чтобы IDE знала о формах, вам нужно их зарегистрировать. В этот момент Вы можете просто открыть свойства непосредственно в Инспекторе объектов.

Проблема в коде заключается в том, что вы не наследуете метод GetPropertiesClass должным образом.

Обратите внимание, что вы не наследуете его через семейство классов.

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

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

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

Comments

    Ничего не найдено.