在 运行 时间分配已发布属性的具体时间是什么时候?

When exactly are published properties assigned at run time?

我有一个自定义控件,它需要根据已发布的 属性 在 运行 时间加载时做一些事情。但是,我 运行 遇到一个问题,每当我检查已发布的 属性 时,它尚未设置,并且始终是默认值。

我首先尝试在控件的构造函数中检查 属性,但很快发现它们尚未加载。我知道当控件显示在屏幕上时,属性设置正确,因此根本没有加载属性不是问题。

接下来我尝试覆盖 Loaded Method 但我仍然遇到同样的问题,所以我不认为这正是我要找的。

void __fastcall TFmSearchBar::Loaded()
{
    TEdit::Loaded(); //call base class loaded

    if( MyProperty )
    {
        //do stuff
    }
}   

这些已发布的属性实际上是在什么时候设置的?

一旦属性设置正确,我挂接什么方法 can/should 以便根据这些属性在我的控件中执行某些逻辑?

If I check the property in the constructor of the control, the property is always the default value even if I have specified otherwise in the designer.

正确,因为尚未分配其设计时值。

At what point are these published properties actually getting set?

在构造所有者(窗体、框架或数据模块)时。它加载自己的 DFM 资源并解析它,构建存储的子组件并读取它们的 属性 值。

例如,假设您有以下 DFM:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ...
  object Edit1: TEdit
    Left = 136
    Top = 64
    Width = 121
    Height = 21
    TabOrder = 0
  end
  object Button1: TButton
    Left = 263
    Top = 62
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 1
  end
end

DFM 流处理过程大致 转换为以下等效代码(为简单起见,我省略了很多内部细节):

__fastcall TCustomForm::TCustomForm(TComponent *Owner)
    : TScrollingWinControl(Owner)
{
    this->FFormState << fsCreating;
    try
    {
        // locate, load, and parse the "Form1" DFM resource ...

        this->FComponentState << csLoading;
        this->Parent = ...;
        this->Name = L"Form1":
        this->FComponentState << csReading;
        this->Left = 0;
        this->Top = 0;
        this->Caption = L"Form1";
        ...

        TEdit *e = new TEdit(this);
        try
        {
            e->FComponentState << csLoading;
            e->Parent = this;
            e->Name = L"Edit1"; // <-- sets the derived Form's 'Edit1' member to this object
            e->FComponentState << csReading;
            e->Left = 136;
            e->Top = 64;
            e->Width = 121;
            e->Height = 21;
            e->TabOrder = 0;
            e->FComponentState >> csReading;
        }
        catch (...)
        {
            delete e;
            throw;
        }

        TButton *b = new TButton(this);
        try
        {
            b->FComponentState << csLoading;
            b->Parent = this;
            b->Name = L"Button1"; // <-- sets the derived Form's 'Button1' member to this object
            b->FComponentState << csReading;
            b->Left = 263;
            b->Top = 62;
            b->Width = 75;
            b->Height = 25;
            b->Caption = L"Button1";
            b->TabOrder = 1;
            b->FComponentState >> csReading;
        }
        catch (...)
        {
            delete b;
            throw;
        }

        this->FComponentState >> csReading;

        ...

        e->Loaded();
        b->Loaded();
        this->Loaded();
    }
    __finally
    {
        this->FFormState >> fsCreating;
    }
}

因此,如您所见,组件的 属性 值在调用其构造函数时尚不可用。

What method can/should I hook into in order to execute some logic in my control based on these properties, as soon as the properties are set correctly?

这取决于属性需要做什么。如果他们需要立即执行操作,您可以直接在他们的 属性 setter 中执行。但是如果他们需要等到其他属性首先被加载(如果一个 属性 依赖于另一个 属性 的值),那么覆盖虚拟 Loaded() 方法,它是自动的在 DFM 流式处理完成后调用。 属性 设置器可以检查 ComponentState 属性 的标志,以了解该组件当前是否 运行 在设计时的表单设计器中,是否为 DFM当前正在流式传输等,然后根据需要采取相应行动。

I attempted overriding the Loaded Method but am still having the same problem

究竟是什么?你没有解释你的实际问题是什么。请 edit your question 提供这些详细信息。

so I don't think this is exactly what I am looking for.

最有可能的是,您可能只是没有正确使用它。