2011-12-22 105 views
1

我想在組件無法加載時向組件添加條件狀態,並通知其用戶(開發人員)此組件無法在設計時加載,並且在運行時(目標用戶可能安全)在運行時無法加載。如何在構造函數中加載組件加載?

如何防止組件在其構造函數中加載以及如何在設計時和運行時安全地從構造函數中顯示消息(異常)?

constructor TSomeComponent.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 

    if csDesigning in ComponentState then 
    if SomeIncompatibleCondition then 
     begin 
     // how to display message (exception) about the wrong 
     // condition and interrupt the loading of the component ? 
     end; 

    // is it possible to do the same at runtime ? 
end; 

謝謝

+0

您的測試是在構造函數中(而不是在Loaded方法中),因爲在從DFM開始載入屬性之前需要消息,是否正確? – mjn 2011-12-22 06:28:54

回答

6

引發異常,如:

constructor TSomeComponent.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    if SomeIncompatibleCondition then 
    raise Exception.Create('Incompatible condition detected!'); 
end; 
2

一種方法:

MyObject := TSomeComponent.Create(Self); 
if (NOT MyObject.CreatedOK) then 
    ... deal with it... 

Public 
    Property CreatedOK: boolean read fCreatedOK; 

constructor TSomeComponent.Create(AOwner: TComponent); 
begin 
    ... 
    fCreatedOK := ThereIsAnIncompatibleCondition; 
end; 

然後,程序員通過創建對象

我們更喜歡這樣做,因爲它避免了大量的異常代碼,這些代碼很麻煩,而且在調試時很麻煩。 (這是另一個話題!)

我們使用的另一種方法是如果構造函數有很多工作,將工作移動到另一個方法,用戶在構建後調用。這也使得我們可以輕鬆地將許多值傳遞給對象。

public 
    constructor Create... 
    function InitAfterCreate:boolean; 
end; 

調用程序:

MyObject := TSomeComponent.Create 
if (NOT MyObject.InitAfterCreate) then 
    ... deal with it ... 

,或者,如果你使用InitAfterCreate傳遞價值,你把它定義爲

function InitAfterCreate(Value1: Integer, etc.):boolean 

然後InitAfterCreate可以檢查的狀態該對象並返回結果。

這些方法的一個弱點是程序員必須記得調用InitAfterCreate或檢查MyObject.CreatedOk。爲了防止他們不這樣做,你可以把你的對象像一些其他的方法開始的一些斷言:

procedure TForm.FormShow 
begin 
    Assert(fCreatedOK, "Programmer failed to check creation result.") 
    ... 
end; 

在所有情況下,一個挑戰是不能終止創建離開該對象的半以不確定的狀態創建,這可能會讓你的析構函數很難知道要銷燬多少。