Класс свойств компонента 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
2 ответов:
Основная проблема здесь заключается в том, что IDE не создает экземпляр вашей формы во время разработки. Таким образом, независимо от того, какой код вы помещаете в класс form, он не будет выполняться IDE. Это происходит потому, что вы не зарегистрировали форму в IDE.
Если вы хотите, чтобы IDE знала о ваших формах, вам нужно зарегистрировать их в IDE. И в этот момент весь ваш код становится ненужным, потому что вы возвращаетесь к тому, чего вы пытаетесь избежать. А именно регистрация бланков с помощью ИНТЕГРИРОВАННАЯ СРЕДА РАЗРАБОТКИ. Вы застряли в ситуации Уловки 22. Если вам нужно, чтобы IDE знала о формах, вам нужно их зарегистрировать. В этот момент Вы можете просто открыть свойства непосредственно в Инспекторе объектов.
Проблема в коде заключается в том, что вы не наследуете метод GetPropertiesClass должным образом.
Обратите внимание, что вы не наследуете его через семейство классов.
В вашем коде каждый тип класса имеет свою собственную версию метода GetPropertiesClass, и поэтому, поскольку вы типизируете владельца в класс TBaseForm, метод из TBaseForm используется, даже если владелец принадлежит классу TSecondForm.
Поэтому вам нужно убедиться, что GetPropertiesClass в классе TBaseForm является виртуальным и что merhod GetPropertiesClass в TSecondForm переопределяется.
Это гарантирует, что TSecondForm.Метод GetProperties будет вызываться даже при типизации владельца в TBaseClass, когда владелец принадлежит классу TSeconfForm.
Comments