2014-12-25 8 views
2

RAD Studio XE5를 사용하여 응용 프로그램을 빌드하고 있습니다.Delphi 구성 요소 속성 클래스 (구성 요소의 Owner 클래스에 따라 다름)

TForm에서 속성을 게시하려고 시도하는 것이 그리 실제적이지 않다는 것을 알았습니다. 그런 다음 패키지로 등록 및 설치해야하며 무거운 개발에는 실용적이지 않습니다.

그래서 양식 속성을 채우는 데 사용되는 비 시각적 구성 요소 (TFormPropertiesEditor)를 만들 것이라고 결정했습니다. 내 양식을 표준화하는 방법.

구성 요소는 기본 폼에 놓이게됩니다.이 폼은 다른 모든 폼이 상속하는 폼입니다 (TBaseForm이라고 함). 따라서 구성 요소는 기본 양식에 한 번만 삭제되고 상속을 받으면 다른 모든 양식에도 적용됩니다.

작성된 구성 요소는 소유자 (BaseForm 또는 그 하위 항목)의 클래스를 감지하고 클래스가 소유자 클래스의 조건부가되는 '등록 정보'등록 정보를 통해 액세스 가능한 오브젝트를 작성합니다.

이 방법을 사용하면 TBaseForm에서 구성 요소를 검사 할 때 TBaseFormProperties에만 액세스 할 수 있습니다. TSecondForm에서 구성 요소를 검사 할 때도 TSecondFormProperties에 액세스 할 수 있습니다. 단지, 구성 요소는 어떤 PropertyClass를 Properties 속성으로 노출해야 하는지를 감지 할 정도로 지능적입니다.

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

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

대응 TProperties이있는 하위과 같이 한 각 형태 : 예

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

:

성분은 GetPropertiesClass 통해 폼을 검사 할은으로서 정의

구성 요소가 배치 된 Form이 TBaseForm 인 경우 FProperties는 TBaseFormProperties가됩니다. 양식이 TSecondForm 인 경우 FProperties는 TSecondFormProperties가됩니다. 당연히 TSecondFormProperties는 TBaseFormProperties에서 상속받습니다.

하지만 구성 요소를 양식에 배치 할 때 구성 요소가 어떤 클래스인지 감지 할 수없는 것 같습니다.

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

TBaseForm (Owner) 부분이 문제를 일으키는 것 같습니다. 인터프리터는 TBaseForm에 고정되어 있으며 Owner가 TSecondForm 또는 TThirdForm 유형인지 여부는 고려하지 않습니다.

인터페이스 그래서

에서, TBaseForm (소유자) 타입 캐스팅 해결하기 위해, 나는 인터페이스를 사용하기로 결정했다.

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;  

다음 : 나는 GetPropertiesClass를 선언하는 인터페이스를 사용하는 경우 있도록 인터페이스로

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

결과를 오류를 지원하지 않습니다.

추상 조상 방법은

다음, 나는 조상의 추가 레이어를 추가하기로 결정했다. TBaseForm이 상속하는 TMasterForm 클래스를 추가했습니다.

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; 

을하지만이 IDE는 물론하지 구현 TMasterClass.GetPropertiesClass를 액세스하려고 생각하기 때문에 다음, 나는 AV를 얻을 :이 TMasterForm은 추상적이고 가상으로 GetPropertiesClass을 선언합니다.

어떻게이 유형 캐스팅을 수행 할 수 있습니까? 어떤 생각을 어떻게 진행할 수 있습니까?

사전

당신에게 대단히 감사합니다 다운로드 샘플 프로젝트 코드의 문제는 당신이 제대로 GetPropertiesClass 방법을 상속하지 않는 것입니다 https://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 메서드가 있으므로 소유자가 TBaseForm 클래스에 typecasting하므로 소유자가 TSecondForm 클래스 인 경우에도 TBaseForm의 메서드가 사용됩니다.

따라서 TBaseForm 클래스의 GetPropertiesClass가 가상이고 TSecondForm의 merhod GetPropertiesClass가 재정의되었는지 확인해야합니다.

이렇게하면 소유자가 TSeconfForm 클래스 일 때 소유자를 TBaseClass로 typecasting하는 경우에도 TSecondForm.GetProperties 메서드가 호출됩니다.

+0

답변 해 주셔서 감사합니다. 나는 그것을 실제로했다. TBaseForm이 상속하는 다른 클래스 인 TMasterForm = class (TForm)도 GetPropertiesClass 추상 및 가상 클래스를 추가했습니다. TBaseForm의 GetPropertiesClass가 오버라이드 된 것으로 선언됩니다. 그래도 구성 요소를 양식에 놓으면 IDE는 TMasterForm의 GetPropertiesClass에 액세스하려고 시도합니다.이 메서드는 AV이므로이 메서드는 abstract입니다. – Ludo